0

HOTP の手動 HMAC SHA-1 切り捨てをカウントしようとしていますが、ソース コードでカウントした場合と同じ結果が返されません。たとえば、HMAC SHA-1 を次のように生成するコードがあります。

$hash = hash_hmac('sha1','375317186160478973','test');

それは私に HMAC = c359e469b8ef0939f83e79a300b20a6ef4b53a05 を与えるでしょう

[19] 個の配列に分割すると、次のようになります。

c3 59 e4 69 b8 ef 09 39 f8 3e 79 a3 00 b2 0a 6e f4 b5 3a 05

最後の配列から 05 (バイナリで 101) を取得し、その後 101 & 0xf = 5 を実行します

だから私は5番目の配列から数えます ef (11101111) 09 (1001) 39 (111001) f8 (11111000)

その後、 (((11101111) & 0x7f) << 24) | を実行します。(((1001) & 0xff) << 16) | (((111001) & 0xff) << 8) | ((11111000) & 0xff)) % pow (10,6)

次のような結果が得られます:56024

しかし、このコードを使用すると:

$offset = ($hash[19]) & 0xf;
$otp    = (((($hash[$offset + 0]) & 0x7f) << 24) |
          ((($hash[$offset + 1]) & 0xff) << 16) |
          ((($hash[$offset + 2]) & 0xff) << 8) |
          (($hash[$offset + 3]) & 0xff)) % pow(10, 6);

次のような結果が得られます:599808

配列からの値として 2 進値または 10 進値を書き込むと、同じ異なる結果が表示されます。誰かが私の過ちを説明するのを手伝ってくれるので、マニュアルとソースコードを数えて、HOTP の同じ値を得ることができます。ありがとうございました

4

1 に答える 1

0

Apa kabar :) まず、SHA-1 のサイズは 19 ではなく 160 ビット (20 バイト) です。PHP を正しく使用していますか? 問題は、常に文字で正確に読み取るだけであるため、そのような配列へのアクセスが機能しないことです。

$hash[5] // (4)
$hash[6] // (6)
$hash[7] // (9)
$hash[8] // (b)

以下が機能するはずです:

((intval(substr($hash, ($offset + 0) * 2, 2), 16) & 0x7f) << 24) |
((intval(substr($hash, ($offset + 1) * 2, 2), 16) & 0xff) << 16) |
((intval(substr($hash, ($offset + 2) * 2, 2), 16) & 0xff) << 8) |
(intval(substr($hash, ($offset + 3) * 2, 2), 16) & 0xff);

重要なのは、$hashphp は文字列のように見えるため、単純に配列としてアクセスすることはできません。これは間違った値を返すためです。ただし、メソッドを使用して文字列のコンポーネントを取得できますsubstr。常に 2 バイトを読み取って整数に変換する必要があります。文字列には 16 進数の値が含まれているため、 では基数 16 を使用する必要がありますintval

PS: ハッシュ文字列の長さはちょうど 20 バイトだと思います。

要約: たとえば $hash[5] は、期待される配列値 0xEF を提供しませんが、5 番目の文字列文字 '4' (部分文字列 E4 の一部) を提供します。

于 2014-12-01T08:25:06.400 に答える