ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
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) 对比发现,计算出来的跟官网上公布的是一致的。