如何用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
相关产品推荐
相关产品推荐

