HMAC 算法


原文链接: HMAC 算法

消息摘要算法-HMAC算法
HMAC算法

HMAC 算法主要应用于身份验证,用法如下:

1.客户端发出登录请求
2.服务器返回一个随机值,在会话记录中保存这个随机值
3.客户端将该随机值作为密钥,用户密码进行 hmac 运算,递交给服务器
4.服务器读取数据库中的用户密码,利用密钥做和客户端一样的 hmac运算,然后与用户发送的结果比较,如果一致,则用户身份合法。

JWT 所使用的HMAC
alg 是是所使用的 hash 算法例如 HMAC SHA256 或 RSA,typ 是 Token 的类型自然就是 JWT。

{
"alg": "HS256",
"typ": "JWT"
}

我们也常把MAC称为HMAC(keyed-Hash Message Authentication Code)。

MAC(Message Authentication Code,消息认证码算法)是含有密钥的散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加入了密钥。
MAC算法集合了MD和SHA算法的优势,并加入密钥的支持,是一种更为安全的消息摘要算法。

MD系列的算法有HmacMD2、HmacMD4、HmacMD5三种算法;
SHA系列的算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512五种算法。

可以简单的理解为: 1. MD5或者SHA提取摘要 2.用MAC进行秘钥加密

这么说是没有错的,而我要补充说明的是这里的秘钥问题,因为HMAC的本意秘钥是要随机生成的,而不是客户端与服务器之前约定好的。

HMAC在实践中它应该是这么用的:

(1)客户端向服务器发起请求,访问登录页面.这时服务器生成一个密钥,把这个密钥存储在session之中,然后将密钥返回给客户端.
(2)客户端填写登录表单,点击提交后,运行HMAC算法,根据密钥将用户信息加密后post到服务器.
(3)服务器读取数据库中的密码,用HMAC将密码和session中的密钥进行加密产生密码的密文,将密文与用户提交的进行比较.
但是我看到大多数的实现都没有随机生成秘钥,而是实现约定好秘钥,在客户端与服务端使用,这样做把HMAC的安全性打了折扣。

这里给出以下HMAC的核心实现,不管秘钥是约定好的,还是随机生成的,都使用到了如下的核心方法

具体的使用还是要看具体情况

public static String encodeHmacSHA1(byte[] data, byte[] key) throws Exception {               
    SecretKey secretKey = new SecretKeySpec(key, "HmacSHA1");   
    Mac mac = Mac.getInstance(secretKey.getAlgorithm());    
    mac.init(secretKey);    
    byte[] digest = mac.doFinal(data);            
    return new HexBinaryAdapter().marshal(digest);  
    //转为十六进制的字符串输出  
}  

//生成秘钥  
public static byte[] initHmacSHA1Key() throws NoSuchAlgorithmException {    
    KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");  //假设使用到的是HmacSHA1方法  
    SecretKey secretKey = generator.generateKey();  
    byte[] key = secretKey.getEncoded();  
return key;  
}  
`