Algorithm:Java加密解密之MAC(消息認證碼)


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM