MD5 消息摘要(數字摘要)
它是把一個文本/文件 通過摘要函數(hash函數)計算出一個結果。然后把文本/文件和摘要結果一同發給接受者
接受者接收到文件之后,也進行摘要,把兩個摘要結果進行對比。如果一致就說明文本/文件和摘要是一致的。
問題
假設A把文件和摘要發給B,中途被C截獲了。C把文件改了,同時把改后的文件進行摘要。然后把改后的文件和重新生成的摘要發給B。
B收到結果之后,進行摘要,對比發現,是一致的。但是此時文件是被篡改過的,B也不知道。接收方並不能察覺到數據被篡改。
所以說,普通的消息摘要不能驗證身份和防篡改!!
解決這個問題,我們可以使用MAC(消息認證碼(帶密鑰的hash函數))去解決。
MAC (全稱 Message Authentication Code),消息認證碼(帶密鑰的Hash函數)
通信實體雙方使用的一種驗證機制,保證消息數據完整性的一種工具,在發送數據之前,發送方首先使用通信雙方協商好的散列函數計算其摘要值。在雙方共享的會話密鑰作用下,由摘要值獲得消息驗證碼。
之后,它和數據一起被發送。接收方收到報文后,首先利用會話密鑰還原摘要值,同時利用散列函數在本地計算所收到數據的摘要值,並將這兩個數據進行比對。若兩者相等,則報文通過認證。
計算摘要的時候,需要一個秘鑰key,沒有秘鑰key就無法計算。
注意:相同的消息,不同的key,摘要結果不同。
java1.8代碼演示
下面使用Java(1.8.0_144)演示計算apache-tomcat-8.5.23.zip文件的消息摘要
package com.security.dgst; import java.nio.file.Files; import java.nio.file.Paths; import java.security.Key; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; public class MacTest { //秘鑰(必須要是通信雙方共享的) static final String STR_KEY = "266f5fe18e714688a083df4ca9f78064"; /** * 其中,Mac.getInstance支持的算法有:HmacMD5、HmacSHA1、HmacSHA256等等 * 全部支持的算法見官方文檔: * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Mac */ public static byte[] mac(String algorithm, Key key, byte[] data) throws Exception { Mac mac = Mac.getInstance(algorithm); //這里是關鍵,需要一個key(這里就是和普通的消息摘要的區別點) mac.init(key); byte[] result = mac.doFinal(data); return result; } public static void main(String[] args) throws Exception { byte[] data = Files.readAllBytes(Paths.get("c:/tmp/apache-tomcat-8.5.23.zip")); Key key = new SecretKeySpec(STR_KEY.getBytes(), ""); //使用MD5算法計算摘要 byte[] md5Digest = mac("HmacMD5", key, data); //使用SHA256算法計算摘要 byte[] shaDigest = mac("HmacSHA256", key, data); //把摘要后的結果轉換成十六進制的字符串(也可以使用Base64進行編碼) System.out.println(Hex.encodeHexString(md5Digest)); System.out.println(Hex.encodeHexString(shaDigest)); } }
Mac.getInstance(algorithm) 參數algorithm可以支持的值除了參考官方文檔,還可以通過如下代碼得出:
Security.getAlgorithms("Mac").forEach(System.out::println);
Java8中,輸出結果如下:
PBEWITHHMACSHA512 PBEWITHHMACSHA224 PBEWITHHMACSHA256 HMACSHA384 PBEWITHHMACSHA384 HMACSHA256 HMACPBESHA1 HMACSHA224 HMACMD5 PBEWITHHMACSHA1 SSLMACSHA1 HMACSHA512 SSLMACMD5 HMACSHA1
輸出結果為:
ce078fe3134fa8b50c595e4e984f88e0
d90eec24b04b81cd235ff8d4e5a9aeb00183e253e44b6ed763328ff97f856200
我們可以使用OpenSSL,加上上面使用的秘鑰key,計算摘要。
對比結果,發現是一致的。
文章轉載至:https://blog.csdn.net/mn960mn/article/details/78174234