HMAC简介及HMAC-SHA256实现Demo
一、什么是HMAC
HMAC是一种使用单向散列函数来构造消息认证码的方法,其中HMAC中的H就是Hash的意思。
HMAC中所使用的单向散列函数并不仅限于一种,任何高强度的单向散列函数都可以被用于HMAC,如果将来设计出的新的单向散列函数,也同样可以使用。
使用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512所构造的HMAC,分别称为HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-384、HMAC-SHA-512。
二、HMAC的计算步骤
1、密钥填充
如果密钥比单向散列函数分组长度要短,就需要在末尾填充0,直到其长度达到单向散列函数的分组长度为止。
如果密钥比分组长度要长,则要用单向散列函数求出密钥的散列值,然后将这个散列值用作HMAC的密钥。
2、填充后的密钥与ipad的XOR
将填充后的密钥与被称为ipad的比特序列进行XOR运算。ipad是将00110110这一比特序列不断循环反复直到达到分组长度所形成的比特序列,其中ipad的i是inner的意思。
XOR运算所得到的值,就是一个和单向散列函数的分组长度相同,且和密钥相关的比特序列。这里将这个比特序列称为ipadkey。
ipad为常量0x36...36,长度为Hash Block Size。
3、与消息组合
随后,将ipadkey与消息组合,也就是将和密钥相关的比特序列(ipadkey)附加在消息的开头。
4、计算散列值
将3的结果输入单向散列函数,并计算出散列值。
5、填充后的密钥与opad的XOR
将填充后的密钥与被称为opad的比特序列进行XOR运算,opad是将01011100这一比特序列不断循环反复直到达到分组长度所形成的比特序列,其中opad的o是outer的意思。
XOR运算所得到的结果也是一个和单向散列函数的分组长度相同,且和密钥相关的比特序列。这里将这个比特序列称为opadkey。
opad为常量0x5c...5c,长度为Hash Block Size。
6、与散列值组合
将4的散列值拼在opadkey后面。
7、计算散列值
将6的结果输入单向散列函数,并计算出散列值,这个散列值就是最终的MAC值。
通过上述流程可以看出,最后得到的MAC值,一定是一个和输入的消息以及密钥都相关的长度固定的比特序列。
三、HMAC应用
HAMC主要应用在身份验证,服务器对访问者进行鉴权,流程如下图所示:
四、HMAC-SHA256实现Demo
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class Sha256_mac { public static String sha256_mac(String message,String key){ String outPut= null; try{ Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(),"HmacSHA256"); sha256_HMAC.init(secret_key); byte[] bytes = sha256_HMAC.doFinal(message.getBytes()); outPut = byteArrayToHexString(bytes); }catch (Exception e){ System.out.println("Error HmacSHA256========"+e.getMessage()); } return outPut; } public static String byteArrayToHexString(byte[] b) { StringBuilder sb = new StringBuilder(); String stmp; for (int n = 0; b != null && n < b.length; n++) { stmp = Integer.toHexString(b[n] & 0XFF); if (stmp.length() == 1) sb.append('0'); sb.append(stmp); } return sb.toString().toLowerCase(); } }