PHP中的HMAC-SHA-256

时间:2016-01-22 22:27:40

标签: php hmac

我必须从这个字符串构建一个autorisation哈希:

kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F

此秘密用于HMAC哈希函数:

LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=

我必须生成的自动化哈希是这样的:

P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=

有些事情要照顾:

  1. 签名必须使用RFC 2104中指定的HMAC-SHA-256构建。
  2. 签名必须使用RFC 4648 Section 5(安全字母表)中指定的Base64 URL兼容进行编码。
  3. 还有一些伪代码用于生成:

    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个字符的长度是正确的。请帮助我找出错误,这个简单的问题需要几个小时,而且没有解决方案。

2 个答案:

答案 0 :(得分:7)

有几件事需要注意:

  1. 您的密钥是base64编码的。在使用php函数之前,你必须解码它。这是你错过的最重要的事情。
  2. Mhash已被Hash分机废弃。
  3. 您希望以自定义方式对输出进行编码,因此您需要来自hmac函数的原始输出(默认情况下,php将对其进行十六进制编码)。
  4. 因此,使用散列扩展会变为:

    $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="
    

答案 1 :(得分:0)

只需使用PHP中提供的 hash_hmac()功能即可。

示例:

hash_hmac('sha256', $string, $secret);

Doc在这里:http://php.net/manual/fr/function.hash-hmac.php