什么是Hmac算法?
Hmac算法就是一种基于密钥的消息认证码算法,是一种更安全的消息摘要算法。
Hmac算法总是和某种哈希算法配合起来用的。例如HmacMD5算法即Hmac+MD5。
- 使用HmacMD5而不是用MD5加salt,有如下好处
- HmacMD5使用的key长度是64字节,更安全;
- Hmac是标准算法,同样适用于SHA-1等其他哈希算法;
- Hmac输出和原有的哈希算法长度一致。
步骤
- 产生秘钥并保存字节数组和字符串
- 创建Hmac加密算法对象,初始化秘钥,加入原数据进行加密
- 将加密结果放入字节数组
(1)HmacMD5算法
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
String passWord = "wbjxxmy";
//1.产生秘钥
//获取HmacMD5秘钥生成器
KeyGenerator generator = KeyGenerator.getInstance("HmacMD5");
//生成秘钥
SecretKey s = generator.generateKey();
System.out.println("秘钥的(字节数组):"+Arrays.toString(s.getEncoded()));
System.out.println("秘钥的(16进制字符串)"+HashTools.bytesToHex(s.getEncoded()));
//2使用秘钥进行加密
//获取Hmac加密算法对象
Mac mac =Mac.getInstance("HmacMD5");
mac.init(s);//初始化秘钥
mac.update(passWord.getBytes());//更新原始加密内容
//3.加密处理并获取加密结果
byte[] by =mac.doFinal();
System.out.println("加密处理后的(字节数组):"+Arrays.toString(by));
System.out.println("加密处理后的(16进制字符串):"+HashTools.bytesToHex(by));
}
}
(2)通过密钥的字节数组,恢复密钥
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
//按照字节数组,恢复Hmac秘钥
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
String passWord = "wbjxxmy";//原始密码
//秘钥(字节数组)
byte[] by = {-28, -112, -19, 41, -43, -89, -119, -6, 79, -102, 104, 52, 24, 16, -105, 60, 58, 124, -6, -24, 32, 29, -20, -123, -18, 38, 93, -2, 85, 51, -117, -96, -118, -127, -57, -79, -18, -57, -10, 102, 25, 11, 95, -32, -25, -112, 8, -4, -54, 117, 13, -32, 24, -52, 5, 80, 46, -126, -41, 4, -25, 80, -76, 124};
//1.恢复秘钥(字节数组)
SecretKey key =new SecretKeySpec(by, "HmacMD5");
//2.创建Hmac加密算法对象
Mac mac = Mac.getInstance("HmacMD5");
mac.init(key);//初始化密钥
mac.update(passWord.getBytes());//加入原数据
//3.将得到的秘钥结果存入字符串
String s = HashTools.bytesToHex(mac.doFinal());
System.out.println(s);
}
}
(3)通过密钥的字符串,恢复密钥
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
//按照字符串,恢复Hmac秘钥
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
String passWord = "wbjxxmy";//原始密码
byte[] by = new byte[64];
//秘钥(字符串)
String s1 = "0e659dbb23b5287316537dd4c9c1b7cf871f7abd42ef93fee47afa3c102aff1dbe06974217383b7cb7199ff1b4875320f04630f473efeda17db96b6a502f9c17";
for(int i =0,k=0;i<s1.length();i+=2,k++) {
String s = s1.substring(i,i+2);
//将16进制的字符串s转换为字节
by[k] = (byte) Integer.parseInt(s,16);
}
//1.恢复秘钥(字节数组)
SecretKey key =new SecretKeySpec(by, "HmacMD5");
//2.创建Hmac加密算法对象
Mac mac = Mac.getInstance("HmacMD5");
mac.init(key);//初始化密钥
mac.update(passWord.getBytes());//加入原数据
//3.将得到的秘钥结果存入字符串
String s = HashTools.bytesToHex(mac.doFinal());
System.out.println(s);
}
}