Hmac算法

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、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));

### HMAC算法的工作原理 HMAC(基于哈希的消息认证码)是一种利用加密散列函数生成消息认证码的技术。它结合了一个秘密密钥和一个输入消息,通过两次哈希运算生成最终的签名值[^1]。 #### 密钥扩展与填充 在 HMAC 的核心过程中,首先会对密钥 \( K \) 进行扩展处理。如果原始密钥长度小于内部块大小,则会将其用零字节填充到指定长度;如果密钥过长,则先对其进行一次哈希压缩再扩展[^4]。 接着分别使用两个固定常量 IPad (0x36) 和 OPad (0x5C),对扩展后的密钥执行 XOR 操作得到中间状态: \[ K_{ipad} = K \oplus IPad,\quad K_{opad} = K \oplus OPad \] 随后进行两轮哈希计算: \[ H(K_{opad} || H(K_{ipad} || message)) \] 其中 `||` 表示字符串连接操作符。 --- ### Python 中 HMAC 算法的具体实现 以下是采用面向对象方法构建的一个简单 HMAC 类实例化并调用了内置 hashlib 库完成主要功能演示: ```python import hmac from abc import ABC, abstractmethod class HashAlgorithm(ABC): @abstractmethod def create_hash(self, key: bytes, msg: bytes) -> str: pass class HMACSHA256(HashAlgorithm): def __init__(self, secret_key: str): self.key = secret_key.encode() def create_hash(self, msg: bytes) -> str: digest_maker = hmac.new(self.key, msg=msg, digestmod='sha256') return digest_maker.hexdigest() if __name__ == "__main__": sha256_instance = HMACSHA256(secret_key="my_secret") result = sha256_instance.create_hash(msg=b"Hello World!") print(f"HMAC SHA256 Result: {result}") ``` 上述代码片段展示了如何创建一个继承自抽象基类的对象,并实现了特定于 SHA-256 的 HMAC 计算逻辑。 --- ### Java 实现 HMAC-MD5 示例 下面是一个简单的例子说明如何在 Java 中生成 HmacMD5 并应用随机数作为密钥[^2]: ```java import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.Key; public class HmacExample { public static void main(String[] args)throws Exception{ String algorithm = "HmacMD5"; Mac macInstance = Mac.getInstance(algorithm); Key secretKey = new SecretKeySpec("secretkey".getBytes(),algorithm); macInstance.init(secretKey); byte[] textToEncryptBytes = "HellArtisan".getBytes(); byte[] encryptedTextArray = macInstance.doFinal(textToEncryptBytes); System.out.println(new sun.misc.BASE64Encoder().encode(encryptedTextArray)); } } ``` 此程序段显示了设置 MAC 实例的过程以及初始化阶段所需的参数配置。 --- ### PHP 手动实现 HMAC 当 hash_hmac 不可用时 当服务器环境不支持原生 `hash_hmac()` 函数时,可以按照如下方式重新编写其基本行为[^3]: ```php function custom_hmac($algo, $data, $key){ if(function_exists('hash_hmac')){ return hash_hmac($algo,$data,$key); } // Manual implementation starts here... $blocksize=64; if(strlen($key)>$blocksize){ $key=str_pad(hash($algo,$key,true),$blocksize,"\0"); }else{ $key=str_pad($key,$blocksize,"\0"); } $ipad=str_repeat(chr(0x36), $blocksize)^$key; $opad=str_repeat(chr(0x5c), $blocksize)^$key; return hash($algo,$opad.hash($algo,$ipad.$data)); } echo(custom_hmac('md5', 'message', 'key')); ``` 这段脚本提供了另一种途径,在缺乏必要扩展的情况下也能获得一致的结果。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Gurean

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

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

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

打赏作者

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

抵扣说明:

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

余额充值