You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用openssl_*函数实现hash_hmac('sha256','data','key')等价功能?

用OpenSSL系列函数实现等价于hash_hmac('sha256', 'data', 'key')的功能

嘿,这个问题问得很到位!其实你不用纠结openssl_digest不支持密钥的问题——PHP里专门有个openssl_hmac函数,能直接实现和hash_hmac('sha256', 'data', 'key')完全一致的效果,用法还特别贴近:

$key = 'your-secret-key';
$data = 'your-data-to-sign';

// 用openssl_hmac实现等价功能
$openssl_hmac_result = openssl_hmac($data, 'sha256', $key, $raw_output = false);
// 对比原生hash_hmac的结果
$hash_hmac_result = hash_hmac('sha256', $data, $key);

// 两者的输出应该完全相同
echo $openssl_hmac_result === $hash_hmac_result ? "结果一致!" : "结果不同";

如果出于特殊需求,你必须用openssl_digest手动实现HMAC逻辑(虽然没必要,但了解原理也很有用),那可以严格遵循HMAC的标准算法步骤来写:

function openssl_hmac_manual(string $data, string $key): string {
    $hash_alg = 'sha256';
    $block_size = 64; // SHA256的块大小固定为64字节

    // 第一步:预处理密钥
    if (strlen($key) > $block_size) {
        // 密钥过长时,先哈希缩短到32字节
        $key = openssl_digest($key, $hash_alg, true);
    } elseif (strlen($key) < $block_size) {
        // 密钥过短时,用\x00填充到区块大小
        $key = str_pad($key, $block_size, "\x00");
    }

    // 生成内部密钥(与0x36逐字节异或)
    $inner_key = $key ^ str_repeat("\x36", $block_size);
    // 生成外部密钥(与0x5C逐字节异或)
    $outer_key = $key ^ str_repeat("\x5C", $block_size);

    // 第一步哈希:内部密钥拼接数据后做摘要
    $inner_hash = openssl_digest($inner_key . $data, $hash_alg, true);
    // 第二步哈希:外部密钥拼接内部哈希后做摘要,得到最终HMAC
    $final_hmac = openssl_digest($outer_key . $inner_hash, $hash_alg, false);

    return $final_hmac;
}

// 测试验证
$test_key = 'my-test-key';
$test_data = 'hello-hmac-world';
echo openssl_hmac_manual($test_data, $test_key) === hash_hmac('sha256', $test_data, $test_key) ? "手动实现结果一致!" : "手动实现结果不同";

核心逻辑就是按照HMAC的定义,通过密钥与固定异或值生成内外两层密钥,分两次完成哈希运算,最终得到和原生hash_hmac完全相同的结果。

内容的提问来源于stack exchange,提问作者Thor Samsberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:19:37