-
简述
HMAC(Hash-based Message Authentication Code)算法,是一种在消息传输过程中防止数据被篡改或篡改后被恶意使用的方法。它是使用hash函数和密钥来计算消息验证码的技术。 HMAC算法可以用来验证任意长度的消息,并且可以防止攻击者通过修改消息和 HMAC 值来使验证通过。
-
算法实现
这个算法类似于我们用一个随机生成的数与被加密的字符串组合进行数据生成,代码实现如下:
String password = "hsxfhs";
//生成随机数并且截取四位
String uuid = UUID.randomUUID().toString().substring(0,4);
///创建基于MD5的消息摘要对象
MessageDigest digest = MessageDigest.getInstance("md5");
//更新数据
digest.update(password.getBytes());
digest.update(uuid.getBytes());
//获得加密数据
System.out.println(Hashtools.BytestoHex(digest.digest()));
这种操作称为加盐,虽然可以在一定程度避免彩虹表等攻击但是还是存在一定安全隐患,毕竟只有四位随机数,为了更加安全保险,使用Hmac算法代码实现如下:
String str = "dwasds";
//1、产生密钥
//获取Hmacmd5密钥生成器
KeyGenerator generator = KeyGenerator.getInstance("Hmacmd5");
//生成密钥
SecretKey key = generator.generateKey();
//输出密钥关联信息
System.out.println("密钥:"+Arrays.toString(key.getEncoded()));
System.out.println("密钥长度(64字节)"+key.getEncoded().length);
System.out.println("密钥:"+Hashtools.BytestoHex(key.getEncoded()));
//2、使用密钥,进行加密
//获取HMac加密算法对象
Mac mac = Mac.getInstance("Hmacmd5");
mac.init(key);
mac.update(str.getBytes());
byte[] bytes = mac.doFinal();
String result = Hashtools.BytestoHex(bytes);
System.out.println("加密结果字节"+bytes.length);
System.out.println("加密结果16进制"+result);
System.out.println("加密结果字符"+result.length());
-
密钥恢复
有了Hmac计算的哈希和SecretKey,我们想要密钥恢复时有两种恢复方式:
- 密钥字节数组恢复
- 密钥字符串恢复
实现代码如下:
String str = "dwasds";
//1、密钥字节数组恢复
byte[] KeyBytes = {22, 110, -83, -55, 30, 89, -38, -86, -35, 5, 39, -83, -54, 20, -124, 97, -33, -5, -104, -62, 59, 39, 46, -90, -74, -25, 54, 99, -106, 5, 98, -5, 80, -127, 31, 16, -51, -72, 105, -53, -74, 17, -101, 123, 115, -66, -85, -33, -11, -12, -22, 43, -109, 6, 54, -20, 108, 85, 48, 65, -10, -118, -46, -22};
//2、密钥字符串恢复
String Keystr = "166eadc91e59daaadd0527adca148461dffb98c23b272ea6b6e73663960562fb50811f10cdb869cbb6119b7b73beabdff5f4ea2b930636ec6c553041f68ad2ea";
//f4ad406c1294f6734d10404a6377e25b加密结果16进制
byte[] KeyBytes = new byte[64];
for(int i =0,k=0;i<Keystr.length();i+=2,k++) {
String s = Keystr.substring(i,i+2);
KeyBytes[k] = (byte)Integer.parseInt(s,16);
}
SecretKey key = new SecretKeySpec(KeyBytes, "HmacMd5");
Mac mac = Mac.getInstance("Hmacmd5");
mac.init(key);
mac.update(str.getBytes());
String result = Hashtools.BytestoHex(mac.doFinal());
System.out.println("结果:"+result);
//f4ad406c1294f6734d10404a6377e25b
代码中方法一二选其一实现或者改变变量名称。