Hmac算法

文章介绍了Hmac算法的概念,它作为加盐的Hash算法,主要特点是搭配Hash算法使用且输出长度与原Hash算法一致。在Java中,通过KeyGenerator生成密钥,然后使用Mac进行加密和验证过程。在验证时,需要从密钥字节数组中恢复密钥字符串。
摘要由CSDN通过智能技术生成

目录

一、Hmac算法概念

1.特点

2.实现

 3.验证

      3.1根据密钥字节数组恢复密钥字符串

      3.2根据密钥字符串恢复密钥数组


一、Hmac算法概念

在Hash算法中,为了抵御彩虹表攻击,需要对口令加盐存储,而Hmac算法相当于加盐的Hhash算法。

1.特点

(1)Hmac算法总是搭配Hash算法使用

(2)输出与原Hash算法长度一致

2.实现

在Hmac算法中,使用key代替盐的位置,在使用时,除了原始口令,还需要提供key,但这个key并不由用户提供,而是通过Java库的KeyGenerator生成。

String password="aaaaaaheimaojingzhang";
//1.生成密钥
//获取密钥生成器
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
SecretKey key = keyGenerator.generateKey();
System.out.println("密钥==>"+Arrays.toString(key.getEncoded()));
System.out.println("密钥长度==>"+key.getEncoded().length);
System.out.println("16进制==>"+HashTools.bytesToHex(key.getEncoded()));

//2.使用密钥进行加密
Mac mac = Mac.getInstance("HmacMD5");
mac.init(key);//初始化密钥
mac.update(password.getBytes());//更新原始加密内容
byte[] bytes = mac.doFinal();//加密处理并获取加密结果
final String result = HashTools.bytesToHex(bytes);
System.out.println(Arrays.toString(bytes));
System.out.println("加密后长度(字节)==>"+bytes.length);
System.out.println("16进制字符串==>"+result);
System.out.println("16进制字符串长度==>"+result.length());

运行结果: 

 3.验证

在验证时,也需要用到SecretKey,但此时的SecretKey不能由KeyGenerator生成,而需要从密钥字节数组中恢复

3.1根据密钥字节数组恢复密钥字符串
//根据密钥字节数组恢复密钥并再次加密
String password="aaaaaaheimaojingzhang";
//密钥字节数组
byte[] keyBytes={119, 125, -66, -92, -35, 88, 92, -27, 101, -21, 97, -103, -111, 24, -103, 64, 16, 84, 65, 71, -5, -60, -78, 92, 89, 74, 100, 39, -99, -83, 109, -60, 8, -23, 101, 22, 62, -82, 49, -44, -53, -33, 24, 4, 65, -25, -24, -126, -91, -111, -78, -123, 107, 112, 30, 87, 96, 0, 107, 110, -2, -32, -111, -91};
//恢复密钥
try {
    //包装密钥对象
    SecretKeySpec key = new SecretKeySpec(keyBytes, "HmacMD5");
    //创建加密对象
    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(key);//初始化密钥
    mac.update(password.getBytes());//更新数据
    String res=HashTools.bytesToHex(mac.doFinal());//计算消息摘要并转换为16进制字符串
    System.out.println(res);
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
} catch (InvalidKeyException e) {
    e.printStackTrace();
}

运行结果:

 3.2根据密钥字符串恢复密钥数组
 //密钥字符串
String keyStr="7a32e1f610671e05b0aaa2de1b4c31281ee5cd12c4ab4ea250ec12a2e2b848a2760cb276b89b51a61d1eec2472eb220f7756eee5741cd156d395325d4ae83567";
//用于保存密钥的字节数组,密钥128位,字节数组长度64
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);

}
System.out.println("密钥==>"+ Arrays.toString(keyBytes));

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gurean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值