上一篇介绍了MD及SHA,接下来我们来说说MAC算法。MAC只要就是加入了密钥。
上一篇:Java加密与解密之消息摘要算法
MAC:Message Authentication Code,消息认证码算法。
MAC算法结合了MD5和SHA算法的优势,加入了密钥的支持,是一种更加安全的消息摘要算法。
MAC兼容了MD和SHA算法的特性,并在此基础上加入了密钥, 因为MAC算法融合了密钥散列函数通常我们也把MAC称为HMAC(keyd-Hash Message Authentication Code)。
MD系列:HmacMD2,HmacMD4,HmacMD5三种算法;
SHA系列:HmacSHA1,HmacSHA224,HmacSHA256,HmacSHA384,HmacSHA512五种算法。
HMAC生成的摘要信息长度与使用的MD或是SHA是对应的。如:HmacSHA256使用这个算法那生成的摘要信息长度就是256个字节。
JDK8支持的算法:
HmacMD5,HmacSHA1,HmacSHA256,HmacSHA384,HmacSHA512
HmacMD2,HmacMD4,HmacSHA224这三种不支持,只用使用第三方库BC(Bouncy Castle)
代码示例:
![9f17fea4c020c0a6cd1a0e837e354d70.png](https://img.php1.cn/3cd4a/1eebe/cd5/21e585a7e21fc7dc.png)
初始化生成密钥
![92c9fe26ab65f141e20228036eafa977.png](https://img.php1.cn/3cd4a/1eebe/cd5/6c257b6ba227cc3e.webp)
通过密钥生成摘要数据
![bb8d31391c290ef20637be80cb83c9fe.png](https://img.php1.cn/3cd4a/1eebe/cd5/e88efe5b0a13a7fa.webp)
测试
package com.pack.security.mac;import java.nio.charset.Charset;import java.util.Base64;import javax.crypto.KeyGenerator;import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;public class HmacSHA1 {// 算法private static final String ALGORITHM = "HmacSHA1" ;/** *
* 初始化HmacSHA1密钥 *
*2020年10月8日 下午2:55:38 *@author xg *@return byte[] 生成的密钥信息 *@throws Exception */public static byte[] initHmacSHA1Key() throws Exception{// 初始化KeyGenerator密钥生成器KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM) ;// 产生密钥SecretKey secretKey = keyGenerator.generateKey() ;// 获取密钥return secretKey.getEncoded() ;}/** *
* HmacSHA1 消息摘要 *
*&#64;author xg *&#64;param data 要加密的数据 *&#64;param key 密钥信息 * &#64;return byte[] 摘要信息 *&#64;throws Exception */public static byte[] encodeHmacSHA1(byte[] data, byte[] key) throws Exception {// 还原密钥SecretKey secretKey &#61; new SecretKeySpec(key, ALGORITHM) ;// 实例化MACMac mac &#61; Mac.getInstance(secretKey.getAlgorithm()) ;// 初始化macmac.init(secretKey) ;// 返回消息摘要return mac.doFinal(data) ;}public static String hex(byte[] digest) {StringBuilder sb &#61; new StringBuilder() ;for (byte b : digest) {String str &#61; Integer.toHexString(b & 0xff) ;if (str.length() <2) {sb.append("0" &#43; str) ;} else {sb.append(str) ;}}return sb.toString() ;}public static void main(String[] args) throws Exception {String message &#61; "我是HmacSHA1算法" ;byte[] key1 &#61; initHmacSHA1Key() ;String strKey1 &#61; Base64.getEncoder().encodeToString(key1) ;byte[] messageDigest1 &#61; encodeHmacSHA1(message.getBytes(Charset.forName("UTF-8")), key1) ;String strDigest1 &#61; hex(messageDigest1) ;System.out.println(strDigest1) ;byte[] key2 &#61; Base64.getDecoder().decode(strKey1.getBytes()) ;byte[] messageDigest2 &#61; encodeHmacSHA1(message.getBytes(Charset.forName("UTF-8")), key2) ;String strDigest2 &#61; hex(messageDigest2) ;System.out.println(strDigest2) ;System.out.println(strDigest1.equals(strDigest2)) ;}}
笔者曾经在一个项目中使用过该算法。当时是有很多的厂商要和我们系统对接&#xff0c;为了安全我们给每一个厂商提供一个密钥&#xff0c;然后厂商按照我们的约定对所有的入参进行签名&#xff0c;我们系统进行安全验证。
其它的算法这里就不演示了&#xff0c;针对自己使用的JDK版本看是否支持你所需要的算法即可&#xff0c;基本上BC支持了我们熟知的所有加解密算法。
到此我们对消息摘要算法进行了简单的介绍和使用。后续还会对对称加密和非对称加密及数字签名算法进行介绍。