PHP 中的 HMAC-SHA-256
HMAC-SHA-256 in PHP
我必须从这个字符串构建授权散列:
kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F
此机密用于 HMAC 哈希函数:
LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=
我必须生成的授权散列是这样的:
P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=
有些事情需要注意:
- 必须使用 RFC 2104 中指定的 HMAC-SHA-256 构建签名。
- 签名必须使用 URL 兼容的 Base64 编码,如 RFC 4648 Section 5(安全字母表)中指定的那样。
还有一些生成的伪代码:
Signatur(Request) = new String(encodeBase64URLCompatible(HMAC-SHA-256(getBytes(Z, "UTF-8"), decodeBase64URLCompatible(getBytes(S, "UTF-8")))), "UTF-8")
我在 PHP 中尝试了各种方法,但尚未找到正确的算法。这是我现在的代码:
if(!function_exists('base64url_encode')){
function base64url_encode($data) {
$data = str_replace(array('+', '/'), array('-', '_'), base64_encode($data));
return $data;
}
}
$str = "kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F";
$sec = "LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=";
$signature = mhash(MHASH_SHA256, $str, $sec);
$signature = base64url_encode($signature);
if($signature != "P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=")
echo "wrong: $signature";
else
echo "correct";
它给出了这个签名:
K9lw3V-k5gOedmVwmO5vC7cOn82JSEXsNguozCAOU2c=
如您所见,44个字符的长度是正确的。请帮我找出错误,这个简单的问题花了我好几个小时,而且还没有解决方案。
有几点需要注意:
- 您的密钥是 base64 编码的。您必须先对其进行解码,然后才能将其与 php 函数一起使用。那是你错过的最重要的事情。
- Mhash 已被 Hash 扩展名废弃。
- 您希望以自定义方式对输出进行编码,因此您需要来自 hmac 函数的原始输出(php,默认情况下 hex-encode 它)。
所以,使用散列扩展这就变成了:
$key = "LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=";
$str = "kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F";
function encode($data) {
return str_replace(['+', '/'], ['-', '_'], base64_encode($data));
}
function decode($data) {
return base64_decode(str_replace(['-', '_'], ['+', '/'], $data));
}
$binaryKey = decode($key);
var_dump(encode(hash_hmac("sha256", $str, $binaryKey, true)));
输出:
string(44) "P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI="
只需使用 hash_hmac() PHP.
中可用的函数
示例:
hash_hmac('sha256', $string, $secret);
我必须从这个字符串构建授权散列:
kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F
此机密用于 HMAC 哈希函数:
LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=
我必须生成的授权散列是这样的:
P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=
有些事情需要注意:
- 必须使用 RFC 2104 中指定的 HMAC-SHA-256 构建签名。
- 签名必须使用 URL 兼容的 Base64 编码,如 RFC 4648 Section 5(安全字母表)中指定的那样。
还有一些生成的伪代码:
Signatur(Request) = new String(encodeBase64URLCompatible(HMAC-SHA-256(getBytes(Z, "UTF-8"), decodeBase64URLCompatible(getBytes(S, "UTF-8")))), "UTF-8")
我在 PHP 中尝试了各种方法,但尚未找到正确的算法。这是我现在的代码:
if(!function_exists('base64url_encode')){
function base64url_encode($data) {
$data = str_replace(array('+', '/'), array('-', '_'), base64_encode($data));
return $data;
}
}
$str = "kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F";
$sec = "LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=";
$signature = mhash(MHASH_SHA256, $str, $sec);
$signature = base64url_encode($signature);
if($signature != "P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=")
echo "wrong: $signature";
else
echo "correct";
它给出了这个签名:
K9lw3V-k5gOedmVwmO5vC7cOn82JSEXsNguozCAOU2c=
如您所见,44个字符的长度是正确的。请帮我找出错误,这个简单的问题花了我好几个小时,而且还没有解决方案。
有几点需要注意:
- 您的密钥是 base64 编码的。您必须先对其进行解码,然后才能将其与 php 函数一起使用。那是你错过的最重要的事情。
- Mhash 已被 Hash 扩展名废弃。
- 您希望以自定义方式对输出进行编码,因此您需要来自 hmac 函数的原始输出(php,默认情况下 hex-encode 它)。
所以,使用散列扩展这就变成了:
$key = "LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=";
$str = "kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F";
function encode($data) {
return str_replace(['+', '/'], ['-', '_'], base64_encode($data));
}
function decode($data) {
return base64_decode(str_replace(['-', '_'], ['+', '/'], $data));
}
$binaryKey = decode($key);
var_dump(encode(hash_hmac("sha256", $str, $binaryKey, true)));
输出:
string(44) "P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI="
只需使用 hash_hmac() PHP.
中可用的函数示例:
hash_hmac('sha256', $string, $secret);