hi,大家好,明天咱们开始介绍音讯摘要算法中的 HMAC(Keyed-Hashing for Message Authentication)音讯认证码算法,MAC(Message Authentication Code,音讯认证码算法)是含有密钥散列函数算法,兼容了 MD 和 SHA 算法的个性,并在此基础上加上了密钥,因而 MAC 算法也常常被称作 HMAC 算法。
MAC
在开始之前,咱们先说下 MAC 算法。在古代的网络中,身份认证是一个常常会用到的性能,在身份认证过程中,有很多种形式能够保障用户信息的平安,而 MAC(message authentication code) 就是一种罕用的办法。
音讯认证码是对音讯进行认证并确认其完整性的技术。通过应用发送者和接收者之间共享的密钥,就能够辨认出是否存在假装和篡改行为。
MAC 是通过【MAC 算法 + 密钥 + 要加密的信息】三个因素一起计算得出的。
同 hash 算法(音讯摘要)相比,音讯摘要只能保障音讯的完整性,即该音讯摘要 B 是这个音讯 A 生成的。而 MAC 算法可能保障音讯的正确性,即判断的确发的是音讯 A 而不是音讯 C。
同公私钥体系相比,因为 MAC 的密钥在发送方和接管方是一样的,所以发送方和接管方都能够来生成 MAC,而公私钥体系因为将公钥和私钥离开,所以减少了不可抵赖性。
MAC 有很多实现形式,比拟通用的是基于 hash 算法的 MAC,比方明天咱们要讲的 HMAC 算法。还有一种是基于分组明码的实现,比方 OMAC, CBC-MAC and PMAC 等。
HMAC
HMAC 算法首先它是基于信息摘要算法的。目前次要汇合了 MD 和 SHA 两大系列音讯摘要算法。其中 MD 系列的算法有 HmacMD2、HmacMD4、HmacMD5 三种算法;SHA 系列的算法有 HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512 五种算法。
HMAC 算法除了须要信息摘要算法外,还须要一个密钥。HMAC 的密钥能够是任何长度,如果密钥的长度超过了摘要算法信息分组的长度,则首先应用摘要算法计算密钥的摘要作为新的密钥。个别不倡议应用太短的密钥,因为密钥的长度与平安强度是相干的。通常选取密钥长度不小于所选用摘要算法输入的信息摘要的长度。
MD 算法的比照
算法 | 摘要长度(bit) | 实现方 |
---|---|---|
HmacMD5 | 128 | JDK、Bouncy Castle、Commons Codec |
HmacSHA1 | 160 | JDK、Bouncy Castle、Commons Codec |
HmacSHA224 | 224 | JDK、Bouncy Castle、Commons Codec |
HmacSHA256 | 256 | JDK、Bouncy Castle、Commons Codec |
HmacSHA384 | 384 | JDK、Bouncy Castle、Commons Codec |
HmacSHA512 | 512 | JDK、Bouncy Castle、Commons Codec |
HMAC 算法实现
JDK 的 HMAC 算法实现
JDK 对于 HMAC 算法的实现:
// 获取 HMAC Key
public static byte[] getHmacKey(String algorithm) {
try {
// 1、创立密钥生成器
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
// 2、产生密钥
SecretKey secretKey = keyGenerator.generateKey();
// 3、获取密钥
byte[] key = secretKey.getEncoded();
// 4、返回密钥
return key;
} catch (Exception e) {throw new RuntimeException(e);
}
}
// HMAC 加密
public static String encryptHmac(byte[] data, byte[] key, String algorithm) {
try {
// 1、还原密钥
SecretKey secretKey = new SecretKeySpec(key, algorithm);
// 2、创立 MAC 对象
Mac mac = Mac.getInstance(algorithm);
// 3、设置密钥
mac.init(secretKey);
// 4、数据加密
byte[] bytes = mac.doFinal(data);
// 5、生成数据
String rs = encodeHex(bytes);
// 6、返回十六进制加密数据
return rs;
} catch (Exception e) {throw new RuntimeException(e);
}
}
Bouncy Castle 的 HMAC 算法实现
Bouncy Castle 对于 HMAC 算法的实现:
// 获取 HMAC Key
public static byte[] getHmacKey(String algorithm) {
try {
// 1、创立密钥生成器
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
// 2、产生密钥
SecretKey secretKey = keyGenerator.generateKey();
// 3、获取密钥
byte[] key = secretKey.getEncoded();
// 4、返回密钥
return key;
} catch (Exception e) {throw new RuntimeException(e);
}
}
// HMAC 加密
public static String encryptHmac(byte[] data, byte[] key, String algorithm) {HMac hmac = generateHmacByAlgorithm(algorithm);
KeyParameter keyParameter = new KeyParameter(key);
hmac.init(keyParameter);
hmac.update(data, 0, data.length);
byte[] rsData = new byte[hmac.getMacSize()];
hmac.doFinal(rsData, 0);
return Hex.toHexString(rsData);
}
Commons Codec 的 HMAC 算法实现
Commons Codec 提供的 HMAC 算法实现:
// 获取 HMAC Key
public static byte[] getHmacKey(String algorithm) {
try {
// 1、创立密钥生成器
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
// 2、产生密钥
SecretKey secretKey = keyGenerator.generateKey();
// 3、获取密钥
byte[] key = secretKey.getEncoded();
// 4、返回密钥
return key;
} catch (Exception e) {throw new RuntimeException(e);
}
}
// HMAC 加密
public static String encryptHmac(byte[] data, byte[] key, String algorithm) {Mac mac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_MD5, key);
return Hex.encodeHexString(mac.doFinal(data));
}
获取残缺代码请拜访:
https://github.com/ForTheDevelopers/JavaSecurity
HMAC 算法的利用
1、能够验证对端用户的合法性
HMAC 算法的一个典型利用是用在“挑战 / 响应”(Challenge/Response)身份认证中,认证流程如下:
(1) 先由客户端向服务器收回一个验证申请,(假如是浏览器的 GET 申请)。
(2) 服务器接到此申请后生成一个随机数并通过网络传输给客户端(此为挑战)。
(3) 客户端将收到的随机数与本人的密钥进行 HMAC 运算并失去一个后果作为认证证据返回给服务器(此为响应)。
(4) 与此同时,服务器也应用该随机数与存储在服务器数据库中的该客户密钥进行 HMAC 运算,如果服务器的运算后果与客户端传回的响应后果雷同,则认为客户端是一个非法用户。
在这个过程中,可能受到平安攻打的是服务器发送的随机数和客户端返回的 HMAC 后果,而对于截获了这两个值的黑客而言这两个值是没有意义的,随机值的引入使 HMAC 只在以后会话中无效,大大加强了安全性和实用性。
2、发消息给对方(或从对方接管音讯)
比方你和对方共享了一个密钥 K,当初你要发消息给对方,既要保障音讯没有被篡改(完整性),又要能证实信息的确是你自己发的(源认证),那么就把原信息和密钥 K 经 HMAC 计算的值一起发过来。对方接到之后,应用本人手中的密钥 K 和原音讯计算一下 HMAC 的值,如果和你发送的 HMAC 统一,那么能够认为这个音讯既没有被篡改也没有假冒。
一般散列算法和 HMAC 算法的区别
一般散列算法就是通过 hash 对要输入的数据进行摘要,接管到数据时,再同样对源数据进行散列,与给定的散列值比拟,看收到的数据与计算的 hash 值是否统一就能够了。
通常来说,传输的数据和散列值是不同的渠道给出的,比方网页上显示 MD5 或 SHA 的散列值,然而下载链接是某个镜像网站的,这并不影响你下载到的文件的正确性。
如果要通过同一个渠道发送数据和散列值的话(比方音讯认证码),就要思考数据和散列值是否会同时被篡改的问题,如果第三方批改了数据,而后进行 MD5 散列,并一块发给接管方,接管方并不能察觉到数据被篡改。
而 HMAC 算法就能够用一把发送方和接管方都有的密钥 key 进行计算,而没有这个密钥 key 的第三方是无奈计算出正确的散列值的,这样就能够避免数据的起源方被篡改。
总结
HMAC 算法目前的利用场景绝对还比拟少,通常会间接应用加密算法来保障起源方的正确性,不过 HMAC 在特定场景下还是有肯定用处的,大家能够依据本人的业务特点来抉择应用哪种加密算法。另外也欢送大家关注咱们的公众号,回复【加解密】获取本系列的全副源码。
创作不易,如果大家喜爱本文,欢送点赞,转发,你的关注是咱们继续前进的能源 ^_^