web-dev-qa-db-ja.com

HMAC-SHA-256 in PHP

この文字列から自動立ち上がりハッシュを作成する必要があります。

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セクション5 (安全なアルファベット)で指定されているように、Base64URL互換でエンコードする必要があります。

生成のために与えられたいくつかの擬似コードもあります:

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文字の長さは正しいです。間違いを見つけるのを手伝ってください。この単純な問題はまだ何時間もかかり、解決策はありません。

6
Richard

注意すべき点がいくつかあります。

  1. キーはbase64でエンコードされています。 php関数で使用する前に、デコードする必要があります。それはあなたが見逃した最も重要なことです。
  2. Mhashは Hash 拡張子によって廃止されました。
  3. 出力をカスタム方式でエンコードする必要があるため、hmac関数からの生の出力が必要になります(デフォルトでは、phpは16進エンコードします)。

したがって、ハッシュ拡張を使用すると、これは次のようになります。

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

PHPで利用可能なhash_hmac()関数を使用するだけです。

例:

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

ここにドキュメント: http://php.net/manual/fr/function.hash-hmac.php

1
Meloman