首頁>技術>

1、引言

業界比較有名的不可逆加密演算法有MD5、SHA和HMAC,MD5和SHA在前面兩講中介紹過,本講介紹一下HMAC的知識和使用方法。

HMAC是Hash-based Message Authentication Code的縮寫,中文可以譯為“基於雜湊的訊息鑑權碼”。

HMAC在IETF的RFC 2104中定義,HMAC提出後,成為了事實上的因特網完全標準,在IPSec、SSL等安全協議中得到了廣泛的應用。使用百度搜索“RFC 2104”,即可得到這篇文件,該文件只有11頁,並提供了HMAC演算法的C語言原始碼,感興趣的朋友可以仔細學習。

2、HMAC原理

RFC 2104文件的標題是HMAC: Keyed-Hashing for Message Authentication,從這個標題,可以看出HMAC是一個使用金鑰的雜湊演算法,可以用於訊息鑑權。

如果把金鑰當成加密演算法中的“鹽值”,我們可以粗略地將HMAC當成一個帶鹽值的雜湊演算法。

使用HMAC,我們可以對訊息的完整性進行認證,也可以對訊息傳送源進行身份認證。

HMAC在1997年就作為RFC技術標準提出,二十多年來,經受住了各種安全性攻擊,充分證明了它的安全性。

3、Java對HMAC的支援

在JDK中,提供了HMAC功能,我們可以很輕鬆地對其進行使用。HMAC相關的類和介面介紹如下:

SecretKey介面:提供了金鑰操作介面;

KeyGenerator類:用於生成SecretKey物件;

SecretKeySpec類:實現了SecretKey介面,可以透過指定的位元組陣列和演算法,得到SecretKeySpec物件;

Mac類:實現了HMAC的功能。

基本上,使用這四個Java類或介面,就可以實現對HMAC的呼叫。

4、HMAC的使用

下面這個例子,透過呼叫JDK的功能,實現了基於SHA256演算法的HMAC演算法的使用。這是完整的原始碼:

package com.flying.hmac;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import javax.crypto.KeyGenerator;import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;@SpringBootApplicationpublic class HmacApplication {    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {        SpringApplication.run(HmacApplication.class, args);        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");        SecretKey secretKey = keyGenerator.generateKey();        printBytes("secret key", secretKey.getEncoded());        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), secretKey.getAlgorithm());        Mac mac = Mac.getInstance(secretKey.getAlgorithm());        mac.init(secretKeySpec);        byte[] source = "abcd".getBytes();        byte[] result =mac.doFinal(source);        printBytes("HMAC of [abcd] is ", result);    }    private static void printBytes(String prompt, byte[] bytes){        if (prompt == null || bytes == null){            return;        }        System.out.print(prompt + ":");        for (int i=0; i<bytes.length; i++){            System.out.printf(" %02X", bytes[i]);        }        System.out.println();    }}

程式的邏輯是每次生成一個金鑰,然後用這個金鑰對“abcd”生成訊息鑑權碼。

這是程式第一次執行的情況:

接著執行第二次,情況如下:

可以看到,由於兩次執行生成的金鑰不同,導致兩次對“abcd”生成的訊息鑑權碼不同。

28
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 安全第9講——對稱加密演算法DES的介紹和使用