侧边栏壁纸
博主头像
Easy to understand and humorous

行动起来,活在当下

  • 累计撰写 39 篇文章
  • 累计创建 4 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

摘要算法(Digest):HMac、SM3

fengyang
2025-07-09 / 0 评论 / 0 点赞 / 11 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Hmac

Hmac算法就是一种基于密钥的 消息认证码算法,它的全称是Hash-based Message Authentication Code,是一种更安全的消息摘要算法。

HMAC是一种基于Hash函数的MAC,其核心思想是将消息(Message)与密钥(Key)通过特定的算法生成一个认证码(Authentication Code),用于验证消息的完整性和真实性。

Hmac算法总是和某种哈希算法配合起来用的。例如,我们使用MD5算法,对应的就是HmacMD5算法,它相当于“加盐”的MD5。

HMAC原理

HMAC算法可以分为三个主要步骤:

  • (1)选择Hash函数:HMAC采用一个固定的Hash函数,如SHA-256、MD5等。Hash函数将任意长度的输入数据转化为固定长度的输出,具有良好的单向性和抗碰撞性。
  • (2)预处理:将消息分成若干块,并对每一块进行填充和分组操作。填充目的是保证消息长度满足Hash函数的要求,分组则是为了方便后续计算。
  • (3)计算认证码:将填充后的消息块与密钥依次经过Hash函数计算,得到认证码。最后,将所有认证码拼接在一起,形成完整的HMAC值。

HMAC应用场景

  • 数据完整性验证:在传输过程中,发送方和接收方可以使用HMAC技术对数据进行加密处理。接收方在接收到数据后,通过相同的HMAC算法计算HMAC值,与发送方提供的HMAC值进行对比,验证数据的完整性。
  • 数字签名:HMAC可用于实现数字签名,确保数据的来源和完整性。发送方使用私钥对HMAC值进行加密,接收方使用公钥进行解密和验证。
  • 访问控制:HMAC可应用于访问控制场景,如HTTP请求头的认证。客户端在发送请求时,附带经过HMAC处理的请求头,服务器端收到请求后,使用相同的HMAC算法计算HMAC值,验证客户端的权限。
  • 无线通信:在无线通信领域,HMAC可用于认证和加密,确保通信的安全性。如WiFi认证中,AP(Access Point)和STA(Station)之间采用HMAC算法进行密钥协商和数据加密。

算法类型

  • HmacMD5
  • HmacSHA1
  • HmacSHA256
  • HmacSHA512
  • ...

HmacMD5

HmacMD5 ≈ md5(secure_random_key, input)

使用HmacMD5而不是用MD5加salt,有如下好处:

  • HmacMD5使用的key长度是64字节,更安全;
  • Hmac是标准算法,同样适用于SHA-1等其他哈希算法;
  • Hmac输出和原有的哈希算法长度一致。

为了保证安全,我们不会自己指定key,而是通过Java标准库的KeyGenerator生成一个安全的随机的key。

代码样例

private static void hmacMD5() throws Exception {
    String[] input = {"Hello", "World"};

    // 还原 SecretKey , 便于验证,比如登录。 此数组可以来自数据库中存储的某个字段。
    byte[] hkey = HexFormat.of().parseHex(
            "b648ee779d658c420420d86291ec70f5" +
                    "cf97521c740330972697a8fad0b55f5c" +
                    "5a7924e4afa99d8c5883e07d7c3f9ed0" +
                    "76aa544d25ed2f5ceea59dcc122babc8");
    SecretKey key = new SecretKeySpec(hkey, "HmacMD5");

    // 打印随机生成的key:
    byte[] skey = key.getEncoded();
    System.out.println("key: " + HexFormat.of().formatHex(skey));

    // 实例化 Mac
    Mac mac = Mac.getInstance(key.getAlgorithm());
    // 初始化 Mac
    mac.init(key);

    for (String s : input) {
        mac.update(s.getBytes("UTF-8"));
    }

    // 执行消息摘要
    byte[] result = mac.doFinal();
    // 16 bytes
    Preconditions.checkArgument(result.length == 16, "不符合期望");
    String rs = HexFormat.of().formatHex(result);
    System.out.println(rs);
    Preconditions.checkArgument(
            StringUtils.equals(rs, "4af40be7864efaae1473a4c601b650ae"), "不符合期望");

}

javascript

const hmacHasher =
        CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA512, /* 密钥 */'key');

hmacHasher.reset();

hmacHasher.update('a12345678');

const hash = hmacHasher.finalize();
return hash + '';

HmacSHA256

private static void hmacSHA256() throws Exception {
    String[] input = {"Hello", "World"};

    // 每次均生成新的 SecretKey。 比如注册。
    KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
    SecretKey key = keyGen.generateKey();

    // 打印随机生成的key:
    byte[] skey = key.getEncoded();
    System.out.println("key: " + HexFormat.of().formatHex(skey));

    // 实例化 Mac
    Mac mac = Mac.getInstance(key.getAlgorithm());
    // 初始化 Mac
    mac.init(key);

    for (String s : input) {
        mac.update(s.getBytes("UTF-8"));
    }

    // 执行消息摘要
    byte[] result = mac.doFinal();
    Preconditions.checkArgument(result.length == 32, "不符合期望");
    String rs = HexFormat.of().formatHex(result);
    // 由于key是每次生成的。因此 rs 不固定。因此不做断言判断。
    System.out.println(rs);
}

javascript

function shaxxx(){
    return CryptoJS.SHA512('a12345678');
}

HmacRIPEMD

return CryptoJS.HmacRIPEMD160('a12345678', 'key');

SM3

SM3是中华人民共和国政府采用的一种密码散列函数标准,SM3 为密码杂凑算法,采用密码散列(hash)函数标准,用于替代 MD5/SHA-1/SHA-2 等国际算法, 是在 SHA-256 基础上改进实现的一种算法。

消息分组长度为 512 位,摘要值长度为 256 位,其中使用了异或、模、模加、移位、与、或、非运算, 由填充、迭代过程、消息扩展和压缩函数所构成。

在商用密码体系中,SM3 主要用于数字签名及验证、消息认证码生成及验证、随机数生成等。 其算法公开,据国家密码管理局表示,其安全性及效率要高于 MD5 算法和 SHA-1 算法,与 SHA-256 相当。

该算法已成为我国电子签名类密码系统、计算机安全登录系统、计算机安全通信系统、数字证书、 网络安全基础设施、安全云计算平台与大数据等领域信息安全的基础技术。

0

评论区