摘要分类:MD SHA MAC 常用于验证数据的完整性,是数据签名算法的核心算法
可以说MAC是在SHA MD基础上发展而来,现也称HMAC算法,兼容了MD和SHA算法的特性,HMAC 摘要长度等同SHA1算法的摘要长度,160位的二进制数!区别就是有无密钥
例子:jdk Hmac实现与Bouncy castle实现
package com.example.encryption;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* @author xuanyouwu
* @email xuanyouwu@163.com
* @time 2016-05-14 20:05
*/
public class MacTest {
private static String SrcData = "xuanyouwu";
public static void log(String s) {
System.out.println("------>" + s);
}
public static void main(String[] args) throws Exception {
log("jdk Hmac:" + jdkHmacMd5(SrcData));
log("jdk Hmac mykey:" + jdkHmacMd5WithMyKey(SrcData));
log("bc Hmac:" + bcHmacMD5(SrcData));
}
//JDK 方式实现 默认密钥
private static String jdkHmacMd5(String src) {
try {
//初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");//名称请参考图
//产生密钥
SecretKey secretKey = keyGenerator.generateKey();
//获取密钥
byte[] key = secretKey.getEncoded();
//还原密钥
SecretKey restoreKey = new SecretKeySpec(key, "HmacMD5");
//实例化MAC
Mac mac = Mac.getInstance(restoreKey.getAlgorithm());
//初始化mac
mac.init(restoreKey);
//执行摘要
byte[] hamcMD5bytes = mac.doFinal(src.getBytes());
return Hex.encodeHexString(hamcMD5bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return "";
}
//JDK 方式实现 自定义密钥
private static String jdkHmacMd5WithMyKey(String src) {
try {
//使用自定义密钥
byte[] key = Hex.decodeHex(new char[]{'a', 'b'});// 必须是16进制的字符,长度必须是2的倍数
//还原密钥
SecretKey restoreKey = new SecretKeySpec(key, "HmacMD5");
//实例化MAC
Mac mac = Mac.getInstance(restoreKey.getAlgorithm());
//初始化mac
mac.init(restoreKey);
//执行摘要
byte[] hamcMD5bytes = mac.doFinal(src.getBytes());
return Hex.encodeHexString(hamcMD5bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (DecoderException e) {
e.printStackTrace();
}
return "";
}
// bouncy castle实现方式
private static String bcHmacMD5(String src) {
HMac hMac = new HMac(new MD5Digest());
hMac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("ab")));// 必须是16进制的字符,长度必须是2的倍数
hMac.update(src.getBytes(), 0, src.getBytes().length);
byte[] bytes = new byte[hMac.getMacSize()];
hMac.doFinal(bytes, 0);
return org.bouncycastle.util.encoders.Hex.toHexString(bytes);
}
}
运行结果:
------>jdk Hmac:6cd35433ba176fcf6fba69e43567242a
------>jdk Hmac mykey:6eceb961c0aaf966888a2d935d3b78dd
------>bc Hmac:6eceb961c0aaf966888a2d935d3b78dd
------>jdk Hmac mykey:6eceb961c0aaf966888a2d935d3b78dd
------>bc Hmac:6eceb961c0aaf966888a2d935d3b78dd