MD5加密 java实现

来源:互联网 发布:mysql bin.000004 编辑:程序博客网 时间:2024/06/07 04:52
  Message Digest Algorithm MD5(中文名为消息摘要算法第 五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。
  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 字节数组长度为:162 数据:QWERFVDSCX 加密之后的结果为:[B@1c2709da 字节数组长度为:163 数据: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 bytes34      * @return35      */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 字符串长度为:322 数据:QWERFVDSCX 加密之后的结果为:ce5b403e336fb819b48b08dbfd39fbf3 字符串长度为:323 数据: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 字符串长度为:322 数据:test1 加密之后的结果为:9d40e1329780d62e 字符串长度为:163 数据:QWERFVDSCX 加密之后的结果为:ce5b403e336fb819b48b08dbfd39fbf3 字符串长度为:324 数据:QWERFVDSCX 加密之后的结果为:336fb819b48b08db 字符串长度为:165 数据:23423KJHkdfg 加密之后的结果为:6a91f81e7809f6f79c753a054543d128 字符串长度为:326 数据:23423KJHkdfg 加密之后的结果为:7809f6f79c753a05 字符串长度为:16
原创粉丝点击