百度百科对MD5的说明是:
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 importjava.security.MessageDigest;2 importjava.security.NoSuchAlgorithmException;3
4
5 public classEncryption1 {6 public static final String MD5="MD5";7 /**
8 * 采用加密算法加密字符串数据9 *@paramstr 需要加密的数据10 *@paramalgorithm 采用的加密算法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 voidmain(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 importjava.security.MessageDigest;2 importjava.security.NoSuchAlgorithmException;3
4 public classEncryption2 {5 public static final String MD5="MD5";6
7 /**
8 * 采用加密算法加密字符串数据9 *@paramstr 需要加密的数据10 *@paramalgorithm 采用的加密算法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 *@parambytes34 *@return
35 */
36 public static String BytesConvertToHexString(byte[] bytes) {37 StringBuffer sb = newStringBuffer();38 for (byteaByte : 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 returnsb.toString();47 }48
49 /**
50 * 采用加密算法加密字符串数据51 *@paramstr 需要加密的数据52 *@paramalgorithm 采用的加密算法53 *@return字节数据54 */
55 public staticString EncryptionStr(String str, String algorithm) {56 //加密之后所得字节数组
57 byte[] bytes =EncryptionStrBytes(str,algorithm);58 returnBytesConvertToHexString(bytes);59 }60 //测试上述方法
61 public static voidmain(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 importjava.io.UnsupportedEncodingException;2 importjava.security.MessageDigest;3 importjava.security.NoSuchAlgorithmException;4
5 public classEncryption3 {6 public static final String MD5="MD5";7 public static final String UTF8="UTF-8";8
9 /**
10 * 采用加密算法加密字符串数据 转成长度为32的字符串11 *@paramstr12 *@paramalgorithm 采用的加密算法13 *@paramcharset 指定转化之后的字符串编码14 *@return
15 */
16 public staticString EncryptionStr32(String str, String algorithm,String charset) {17 //加密之后所得字节数组
18 byte[] bytes =EncryptionStrBytes(str,algorithm,charset);19 returnBytesConvertToHexString(bytes);20 }21
22 /**
23 * 采用加密算法加密字符串数据 转成长度为32的字符串24 *@paramstr 需要加密的数据25 *@paramalgorithm 采用的加密算法26 *@return字节数据27 */
28 public staticString EncryptionStr32(String str, String algorithm) {29 return EncryptionStr32(str,algorithm,"");30 }31
32
33 /**
34 * 采用加密算法加密字符串数据 转成长度为16的字符串35 *@paramstr36 *@paramalgorithm 采用的加密算法37 *@paramcharset 指定转化之后的字符串编码38 *@return
39 */
40 public staticString EncryptionStr16(String str, String algorithm,String charset) {41 return EncryptionStr32(str,algorithm,charset).substring(8,24);42 }43
44 /**
45 * 采用加密算法加密字符串数据 转成长度为16的字符串46 *@paramstr 需要加密的数据47 *@paramalgorithm 采用的加密算法48 *@return字节数据49 */
50 public staticString EncryptionStr16(String str, String algorithm) {51 return EncryptionStr32(str,algorithm,"").substring(8,24);52 }53
54 /**
55 * 采用加密算法加密字符串数据56 *@paramstr 需要加密的数据57 *@paramalgorithm 采用的加密算法58 *@paramcharset 指定转化之后的字符串编码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 *@parambytes85 *@return
86 */
87 public static String BytesConvertToHexString(byte[] bytes) {88 StringBuffer sb = newStringBuffer();89 for (byteaByte : 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 returnsb.toString();98 }99
100 //测试上述方法
101 public static voidmain(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