消息认证码算法简介
在密码学中,消息认证码(英语:Message authentication code,缩写为MAC),又译为消息鉴别码、文件消息认证码、讯息鉴别码、信息认证码,是经过特定算法后产生的一小段信息,检查某段消息的完整性,以及作身份验证。它可以用来检查在消息传递过程中,其内容是否被更改过,不管更改的原因是来自意外或是蓄意攻击。同时可以作为消息来源的身份验证,确认消息的来源。
消息认证码的算法中,通常会使用使用带密钥的散列函数,或者块密码的带认证工作模式(如CBC)。
信息鉴别码不能提供对信息的保密,若要同时实现保密认证,同时需要对信息进行加密。
消息认证码算法实现
在Java中支持的消息摘要算法有:HmacMD5、HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512等。
package com.jianggujin.codec;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import com.jianggujin.codec.util.JCodecException;
/**
* 消息认证码(Message Authentication Code,MAC)算法
*
* @author jianggujin
*
*/
public class JMac {
/**
* Mac算法
*
* @author jianggujin
*
*/
public static enum JMacAlgorithm {
HmacMD5, HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA384, HmacSHA512;
public String getName() {
return this.name();
}
}
/**
* 初始化密钥
*
* @param algorithm
* @return
*/
public static byte[] initKey(String algorithm) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (Exception e) {
throw new JCodecException(e);
}
}
/**
* 加密
*
* @param data
* @param key
* @param algorithm
* @return
*/
public static byte[] encrypt(byte[] data, byte[] key, String algorithm) {
return getMac(key, algorithm).doFinal(data);
}
private static Mac getMac(byte[] key, String algorithm) {
try {
Mac mac = Mac.getInstance(algorithm);
SecretKey secretKey = new SecretKeySpec(key, algorithm);
mac.init(secretKey);
return mac;
} catch (Exception e) {
throw new JCodecException(e);
}
}
}
编写测试代码:
package com.jianggujin.codec.test;
import org.junit.Test;
import com.jianggujin.codec.JBase64;
import com.jianggujin.codec.JBase64.JEncoder;
import com.jianggujin.codec.JHex;
import com.jianggujin.codec.JMac;
import com.jianggujin.codec.JMac.JMacAlgorithm;
public class MacTest {
String str = "jianggujin";
@Test
public void test() throws Exception {
System.out.println("原串:" + str);
JEncoder encoder = JBase64.getEncoder();
for (JMacAlgorithm algorithm : JMacAlgorithm.values()) {
System.out.println("-----------------------------------------");
System.out.println("算法:" + algorithm.getName());
byte[] key = JMac.initKey(algorithm.getName());
System.out.println("密钥:" + encoder.encodeToString(key, "UTF-8"));
byte[] result = JMac.encrypt(str.getBytes(), key, algorithm.getName());
System.out.println("结果:" + JHex.encodeString(result));
}
}
}
运行结果如下:
原串:jianggujin
—————————————–
算法:HmacMD5
密钥:FBda1oUidOqnCurm2KeD2KtNVEYYWNiMK8cYLD4bOu1/1P6kTyvBG55u2EplXFWJWFUuBYGh2+s9b3ktET0LlQ==
结果:A90F63F7529F1049850E71B2C3A14C4F
—————————————–
算法:HmacSHA1
密钥:JGGC6NGpDtyLIZqWHZeKqX3HelbpMGpCnrPl/IVg3M8IDno1DU8HSrQYy6G97LzGa6NceP+UgFpfhp0scWeDpQ==
结果:FD5A124932650247BE0D56C6621B1306DEB21199
—————————————–
算法:HmacSHA224
密钥:QucKsrBlIYQ5FvQamhUVq2eP0yU6n1QKzvCOiQ==
结果:BCEA800B557F0E18729163A11171951AB0E854A72287262AD52DE1EA
—————————————–
算法:HmacSHA256
密钥:/cF5NhHeMXj6zlb23bzvhG0elUwTqP4GQ7+FTb17FpE=
结果:5263AC216CBBC1F9818863B9949AB4E0C57280BF0BE3F5714CA01B0D09B4CC24
—————————————–
算法:HmacSHA384
密钥:iSbWZV3bqbc0NlbtL3clu8AUjwO8CzqhTm5jq85H6bTx/1WDaDoulqAQhALRZgG1
结果:B02E27150CE84D5925F37030D93656AC76C2160C836FF9663582E36042FFF0F874DCA0607475F5665F60D82303BA0587
—————————————–
算法:HmacSHA512
密钥:cN5JZWAY+CftCJTE/tb2qGccEnSpZTa1qSXSLEIRo/yWP5p3kX8YRtxxV1g882JKIfp3zRWurmA0GI2w0MeRcA==
结果:901173D5E98A327CA552F831B3ABDDBE5985451AA36EC5A012B2CD3724D7336F3665070657BF86E7DDE407EA715716C4A2331900811A971719FC798AC45AB6E4