• 2 MD5加密 java实现


      百度百科对MD5的说明是:

      Message Digest Algorithm MD5(中文名为消息摘要算法第 五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。
    MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3MD4
      MD5算法具有以下特点:
    1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
    2、容易计算:从原数据计算出MD5值很容易。
    3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
    4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

      MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。

          通常采用java提供的API实现的MD5加密程序如下所示:

     1 import java.security.MessageDigest;
     2 import java.security.NoSuchAlgorithmException;
     3 
     4 
     5 public class Encryption1 {
     6     public static final String MD5="MD5";
     7     /**
     8      * 采用加密算法加密字符串数据
     9      * @param str   需要加密的数据
    10      * @param algorithm 采用的加密算法
    11      * @return 字节数据
    12      */
    13     public static byte[] EncryptionStr(String str, String algorithm) {
    14         // 加密之后所得字节数组
    15         byte[] bytes = null;
    16         try {
    17             // 获取MD5算法实例 得到一个md5的消息摘要
    18             MessageDigest md = MessageDigest.getInstance(algorithm);
    19             //添加要进行计算摘要的信息
    20             md.update(str.getBytes());
    21             //得到该摘要
    22             bytes = md.digest();
    23         } catch (NoSuchAlgorithmException e) {
    24             System.out.println("加密算法: "+ algorithm +" 不存在: ");
    25         }
    26         return null==bytes?null:bytes;
    27     }
    28     //测试上述方法
    29     public static void main(String[] args) {
    30         String test1="test1";
    31         String test2="QWERFVDSCX";
    32         String test3="23423KJHkdfg";
    33         String [] test={test1,test2,test3};
    34         for (String s : test) {
    35             byte [] bytes=EncryptionStr(s,MD5);
    36             System.out.println("数据:" + s+" 加密之后的结果为:"+bytes.toString()+" 字节数组长度为:"+bytes.length);
    37         }
    38     }
    39 }

    上述代码执行结果为:

    1 数据:test1 加密之后的结果为:[B@71881149 字节数组长度为:16
    2 数据:QWERFVDSCX 加密之后的结果为:[B@1c2709da 字节数组长度为:16
    3 数据:23423KJHkdfg 加密之后的结果为:[B@46f7d5a6 字节数组长度为:16

    分析:字符串采用MD5加密之后返回的数据类型为字节数组(byte []),一个字节是8位(bit位),返回的数组长度是16,那么加密的字符串结果为16*8=128位,为固定长度的字节数组,除了MD5代码之外,上述代码中algorithm参数改成SHA-1 、SHA-256等加密算法也是支持的

      上述加密结果通常转成长度为32的字符串进行存储和传输,下面是程序代码:

     1 import java.security.MessageDigest;
     2 import java.security.NoSuchAlgorithmException;
     3 
     4 public class Encryption2 {
     5     public static final String MD5="MD5";
     6 
     7     /**
     8      * 采用加密算法加密字符串数据
     9      * @param str   需要加密的数据
    10      * @param algorithm 采用的加密算法
    11      * @return 字节数据
    12      */
    13     public static byte[] EncryptionStrBytes(String str, String algorithm) {
    14         // 加密之后所得字节数组
    15         byte[] bytes = null;
    16         try {
    17             // 获取MD5算法实例 得到一个md5的消息摘要
    18             MessageDigest md = MessageDigest.getInstance(algorithm);
    19             //添加要进行计算摘要的信息
    20             md.update(str.getBytes());
    21             //得到该摘要
    22             bytes = md.digest();
    23         } catch (NoSuchAlgorithmException e) {
    24             System.out.println("加密算法: "+ algorithm +" 不存在: ");
    25         }
    26         return null==bytes?null:bytes;
    27     }
    28 
    29 
    30 
    31     /**
    32      * 把字节数组转化成字符串返回
    33      * @param bytes
    34      * @return
    35      */
    36     public static String BytesConvertToHexString(byte [] bytes) {
    37         StringBuffer sb = new StringBuffer();
    38         for (byte aByte : bytes) {
    39           String s=Integer.toHexString(0xff & aByte);
    40             if(s.length()==1){
    41                 sb.append("0"+s);
    42             }else{
    43                 sb.append(s);
    44             }
    45         }
    46         return sb.toString();
    47     }
    48 
    49     /**
    50      * 采用加密算法加密字符串数据
    51      * @param str   需要加密的数据
    52      * @param algorithm 采用的加密算法
    53      * @return 字节数据
    54      */
    55     public static String EncryptionStr(String str, String algorithm) {
    56         // 加密之后所得字节数组
    57         byte[] bytes = EncryptionStrBytes(str,algorithm);
    58         return BytesConvertToHexString(bytes);
    59     }
    60     //测试上述方法
    61     public static void main(String[] args) {
    62         String test1="test1";
    63         String test2="QWERFVDSCX";
    64         String test3="23423KJHkdfg";
    65         String [] test={test1,test2,test3};
    66         for (String s : test) {
    67             String str=EncryptionStr(s,MD5);
    68             System.out.println("数据:" + s+" 加密之后的结果为:"+str+" 字符串长度为:"+str.length());
    69         }
    70     }
    71 }

     上述代码执行结果为:

    1 数据:test1 加密之后的结果为:5a105e8b9d40e1329780d62ea2265d8a 字符串长度为:32
    2 数据:QWERFVDSCX 加密之后的结果为:ce5b403e336fb819b48b08dbfd39fbf3 字符串长度为:32
    3 数据:23423KJHkdfg 加密之后的结果为:6a91f81e7809f6f79c753a054543d128 字符串长度为:32

           上述代码虽然实现了基本的数据加密功能,但是有人可能觉得32位字符串还是太长了,想改成16位或者其他长度;或者说java编码时工程统一使用UTF-8编码,对字符串编码格式进行指定等要求,下面是一种实现(功能可扩充点还有很多,比如说字符串数组加密,把加密之后的数据转成指定编码格式等)

      1 import java.io.UnsupportedEncodingException;
      2 import java.security.MessageDigest;
      3 import java.security.NoSuchAlgorithmException;
      4 
      5 public class Encryption3 {
      6     public static final String MD5="MD5";
      7     public static final String UTF8="UTF-8";
      8 
      9     /**
     10      *  采用加密算法加密字符串数据 转成长度为32的字符串
     11      * @param str
     12      * @param algorithm 采用的加密算法
     13      * @param charset 指定转化之后的字符串编码
     14      * @return
     15      */
     16     public static String EncryptionStr32(String str, String algorithm,String charset) {
     17         // 加密之后所得字节数组
     18         byte[] bytes = EncryptionStrBytes(str,algorithm,charset);
     19         return BytesConvertToHexString(bytes);
     20     }
     21 
     22     /**
     23      * 采用加密算法加密字符串数据  转成长度为32的字符串
     24      * @param str   需要加密的数据
     25      * @param algorithm 采用的加密算法
     26      * @return 字节数据
     27      */
     28     public static String EncryptionStr32(String str, String algorithm) {
     29         return EncryptionStr32(str,algorithm,"");
     30     }
     31 
     32 
     33     /**
     34      *  采用加密算法加密字符串数据  转成长度为16的字符串
     35      * @param str
     36      * @param algorithm 采用的加密算法
     37      * @param charset 指定转化之后的字符串编码
     38      * @return
     39      */
     40     public static String EncryptionStr16(String str, String algorithm,String charset) {
     41         return EncryptionStr32(str,algorithm,charset).substring(8,24);
     42     }
     43 
     44     /**
     45      * 采用加密算法加密字符串数据 转成长度为16的字符串
     46      * @param str   需要加密的数据
     47      * @param algorithm 采用的加密算法
     48      * @return 字节数据
     49      */
     50     public static String EncryptionStr16(String str, String algorithm) {
     51         return EncryptionStr32(str,algorithm,"").substring(8,24);
     52     }
     53 
     54     /**
     55      * 采用加密算法加密字符串数据
     56      * @param str   需要加密的数据
     57      * @param algorithm 采用的加密算法
     58      * @param charset 指定转化之后的字符串编码
     59      * @return 字节数据
     60      */
     61     public static byte[] EncryptionStrBytes(String str, String algorithm, String charset) {
     62         // 加密之后所得字节数组
     63         byte[] bytes = null;
     64         try {
     65             // 获取MD5算法实例 得到一个md5的消息摘要
     66             MessageDigest md = MessageDigest.getInstance(algorithm);
     67             //添加要进行计算摘要的信息
     68             if(null==charset||"".equals(charset)) {
     69                 md.update(str.getBytes());
     70             }else{
     71                 md.update(str.getBytes(charset));
     72             }
     73             //得到该摘要
     74             bytes = md.digest();
     75         } catch (NoSuchAlgorithmException e) {
     76             System.out.println("加密算法: "+ algorithm +" 不存在: ");
     77         } catch (UnsupportedEncodingException e) {
     78             System.out.println("数据加密指定的编码格式不支持: " + charset);
     79         }
     80         return null==bytes?null:bytes;
     81     }
     82     /**
     83      * 把字节数组转化成字符串返回
     84      * @param bytes
     85      * @return
     86      */
     87     public static String BytesConvertToHexString(byte [] bytes) {
     88         StringBuffer sb = new StringBuffer();
     89         for (byte aByte : bytes) {
     90             String s=Integer.toHexString(0xff & aByte);
     91             if(s.length()==1){
     92                 sb.append("0"+s);
     93             }else{
     94                 sb.append(s);
     95             }
     96         }
     97         return sb.toString();
     98     }
     99 
    100     //测试上述方法
    101     public static void main(String[] args) {
    102         String test1="test1";
    103         String test2="QWERFVDSCX";
    104         String test3="23423KJHkdfg";
    105         String [] test={test1,test2,test3};
    106         for (String s : test) {
    107             String str=EncryptionStr32(s, MD5, UTF8);
    108             System.out.println("数据:" + s+" 加密之后的结果为:"+str+" 字符串长度为:"+str.length());
    109             str = EncryptionStr16(s, MD5, UTF8);
    110             System.out.println("数据:" + s+" 加密之后的结果为:"+str+" 字符串长度为:"+str.length());
    111         }
    112     }
    113 }

      程序运行结果:

    1 数据:test1 加密之后的结果为:5a105e8b9d40e1329780d62ea2265d8a 字符串长度为:32
    2 数据:test1 加密之后的结果为:9d40e1329780d62e 字符串长度为:16
    3 数据:QWERFVDSCX 加密之后的结果为:ce5b403e336fb819b48b08dbfd39fbf3 字符串长度为:32
    4 数据:QWERFVDSCX 加密之后的结果为:336fb819b48b08db 字符串长度为:16
    5 数据:23423KJHkdfg 加密之后的结果为:6a91f81e7809f6f79c753a054543d128 字符串长度为:32
    6 数据:23423KJHkdfg 加密之后的结果为:7809f6f79c753a05 字符串长度为:16
  • 相关阅读:
    canvas学习-----1px线条模糊问题
    canvas学习-----画直线
    关于开发的一些流程和个人理解
    vue+vue-cli+vuex+vrouter 开发学习和总结
    mac下配置Apache虚拟域名方案,以及遇到的坑
    添加js,css 版本号?v= hash
    webstorm 格式化代码及常用快捷键
    vue+webpack 遇到的问题总结
    vue.js的devtools安装
    Mongodb 新版配置文件详解
  • 原文地址:https://www.cnblogs.com/yangh2016/p/5714504.html
Copyright © 2020-2023  润新知