1.消息摘要简介
消息摘要(Message Digest)又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。因此消息摘要保证了消息的完整性。 消息摘要采用单向Hash 函数将需加密的明文"摘要"成一串128bit(16byte)的密文,这一串密文亦称为数字指纹(Finger Print),它有固定的长度,且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。这样这串摘要便可成为验证明文是否是"真身"的"指纹"了。
常见是算法:
MD5、SHA、CRC 等。
使用场景:
1. 对用户密码进行 md5 加密后保存到数据库里
2. 软件下载站使用消息摘要计算文件指纹,防止被篡改
3. 数字签名(后面知识点)
比如Tomcat的官方下载网页,为了防止下载的Tomcat是“假冒”的,提供了MD5码,我们将Tomcat的zip文件下载后计算一下MD5,如果计算出来的MD5跟官方公布的MD5一致,那么说明我们下载的就是纯正的了。
http://tomcat.apache.org/download-70.cgi
![](https://box.kancloud.cn/2680f07f6f479e5816320c8a42088b4f_588x518.jpg)
2.MD5算法原理
对MD5算法简要的叙述可以为:MD5以512bit分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
第一步、填充:如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N*512+448(bit);
第二步、记录信息长度:用64位来存储填充前信息长度。这64位加在第一步结果的后面,这样信息长度就变为N*512+448+64=(N+1)*512位。
第三步、装入标准的幻数(四个整数):标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定义应该是(A=0X67452301L,B=0XEFCDAB89L,C=0X98BADCFEL,D=0X10325476L)。有点晕哈,其实想一想就明白了。
第四步、四轮循环运算:循环的次数是分组的个数(N+1)
参考文章:http://blog.csdn.net/forgotaboutgirl/article/details/7258109
![](https://box.kancloud.cn/c52526ade3307841f59d6b6e3b94a446_280x280.jpg)
3.MD5的安全性
普遍认为MD5是很安全的,因为暴力破解的时间是一般人无法接受的。实际上如果把用户的密码MD5处理后再存储到数据库,其实是很不安全的。因为用户的密码是比较短的,而且很多用户的密码都使用生日,手机号码,身份证号码,电话号码等等。或者使用常用的一些吉利的数字,或者某个英文单词。如果我把常用的密码先MD5处理,把数据存储起来,然后再跟你的MD5结果匹配,这时我就有可能得到明文。比如某个MD5破解网站http://www.cmd5.com/default.aspx
![](https://box.kancloud.cn/b85ef85adb491244a8b88160c0f98d95_280x280.jpg)
我把其网站下的公告复制如下:
本站针对md5等全球通用公开的加密算法进行反向查询,建立了密文对应查询数据库,很多复杂密文只有本站才可查询,支持多种算法,实时查询记录超过24万亿条,共占用160T硬盘,成功率95%以上,建站十年,国内外享有盛誉。
4.MD5 算法实现
~~~
1. package com;
2.
3. import java.io.File;
4. import java.io.FileInputStream;
5. import java.io.FileNotFoundException;
6. import java.io.IOException;
7. import java.security.MessageDigest;
8. import java.security.NoSuchAlgorithmException;
9.
10. public class MD5Test {
11.
12. public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
13. String str = "你好黑马";
14. String result = getMD5(str);
15. System.out.println(result);
16. File file = new File("C:\\tomcat\\apache-tomcat-7.0.77-windows-x64.zip");
17. String result2 = getMD5(file);
18. System.out.println("下载的Tomact的MD5="+result2);
19. }
20.
21. //获取文件的MD5值
22. private static String getMD5(File file) throws NoSuchAlgorithmException, IOException {
23. MessageDigest messageDigest = MessageDigest.getInstance("MD5");
24.
25. FileInputStream fis = new FileInputStream(file);
26. int len;
27. byte[] buffer = new byte[1024];
28. while((len=fis.read(buffer))!=-1){
29. messageDigest.update(buffer, 0, len);
30. }
31. fis.close();
32.
33. byte[] digest = messageDigest.digest();
34. //对计算结果进行16进制编码
35. return Hex.encode(digest);
36. }
37.
38. //获取字符串的MD5值
39. private static String getMD5(String str) throws NoSuchAlgorithmException {
40. MessageDigest messageDigest = MessageDigest.getInstance("MD5");
41. byte[] digest = messageDigest.digest(str.getBytes());
42.
43. return Hex.encode(digest);
44. }
45.
46. }
~~~
上面代码中,我们对下载的文件进行了MD5计算,得到的值如下图所示:
![](https://box.kancloud.cn/1aec84ae125a0d5a4ada4a829dfcb24d_629x136.jpg)
官网上公布的Tomact的MD5如下图所示。
![](https://box.kancloud.cn/acb1018e79b3edc0026134ebca813864_877x138.jpg)
对比发现,计算的结果跟官方公布的MD5值是一致的,因此可以认为我们下载的Tomcat的真的。
5.SHA算法实现
安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准 (Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160bit(20byte)的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。
SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要,(但会有1x10 ^ 48分之一的机率出现相同的消息摘要,一般使用时忽略)。
SHA算法还有子算法,比如SHA-256和SHA-512。分别代表会产生256位和512位的消息摘要。
SHA的代码实现跟MD5在使用上是一致的。只需要将算法名称改为SHA即可。
~~~
1. package com;
2.
3. import java.io.File;
4. import java.io.FileInputStream;
5. import java.io.FileNotFoundException;
6. import java.io.IOException;
7. import java.security.MessageDigest;
8. import java.security.NoSuchAlgorithmException;
9.
10. public class SHATest {
11. public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
12. String str = "你好黑马";
13. String result = getSHA(str);
14. System.out.println(result);
15. File file = new File("C:\\tomcat\\apache-tomcat-7.0.77-windows-x64.zip");
16. String result2 = getSHA(file);
17. System.out.println("下载的Tomact的SHA="+result2);
18. }
19.
20. private static String getSHA(File file) throws NoSuchAlgorithmException, IOException {
21. MessageDigest messageDigest = MessageDigest.getInstance("SHA");
22. FileInputStream fis = new FileInputStream(file);
23. int len;
24. byte[] buffer = new byte[1024];
25. while((len=fis.read(buffer))!=-1){
26. messageDigest.update(buffer, 0, len);
27. }
28. fis.close();
29.
30. byte[] digest = messageDigest.digest();
31. //对计算结果进行16进制编码
32. return Hex.encode(digest);
33. }
34.
35. private static String getSHA(String str) throws NoSuchAlgorithmException {
36. MessageDigest messageDigest = MessageDigest.getInstance("SHA");
37. byte[] digest = messageDigest.digest(str.getBytes());
38. return Hex.encode(digest);
39. }
40.
41. }
~~~
官网上公布的Tomact的SHA值如下图所示:
![](https://box.kancloud.cn/dcce75850a8f155010df430d2270fba8_852x143.jpg)
我们自己算出来的SHA值如下图所示。
![](https://box.kancloud.cn/48ca1fb503b273e82775f3c7bfc8462d_659x111.png)
对比发现,计算出来的跟官网上公布的是一致的。