【问题标题】:HMAC SHA-1 Truncate HOTP LogicHMAC SHA-1 截断 HOTP 逻辑
【发布时间】:2014-12-01 07:51:43
【问题描述】:

我正在尝试计算 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)

它给我的结果是: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

如果我将二进制或十进制值写为数组中的值,将显示相同的不同结果。有人可以帮我解释我的错在哪里,这样我就可以计算手册和源代码,并给我一个相同的 HOTP 值。谢谢

【问题讨论】:

    标签: arrays truncate hmacsha1 one-time-password rfc-4226


    【解决方案1】:

    Apa kabar :) 首先,SHA-1 的大小是 160 位(20 字节)而不是 19。您使用的是 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);
    

    重要的是,由于$hash 似乎是 php 一个字符串,你不能简单地将它作为数组访问,因为这会返回错误的值。但是您可以借助 substr 方法获取字符串的组成部分。您总是必须读取 2 个字节并将其转换为整数。由于字符串包含十六进制值,您必须在 intval 中使用基数 16。

    PS:我假设哈希字符串的长度正好是 20 个字节。

    总结:例如 $hash[5] 不会为您提供预期的数组值 0xEF,但它会为您提供第 5 个字符串字符“4”(子字符串 E4 的一部分)。

    【讨论】:

    • 卡巴尔·拜克,丹克 :)。谢谢你的回复先生。我不太了解数组,因为这是我第一次尝试解码如何将 HOTP(RFC 4226)截断为 6 位数字。而且我正在尝试与此处相同:goo.gl/LljCZ0,此处:goo.gl/ovosgA 和此处:goo.gl/JEEQwW 将返回不同的 HOTP 值,并且我无法更改 RFC 4226 给出的截断公式,这是我的结果:goo.gl/S0aUqT。它将十六进制转换为十进制值。请先生指教:)
    • @GudangGaram 我已经更新了我的解释。我不确切知道 HOTP 算法,但似乎这不是你的问题。问题是您如何访问存储在字符串而不是数组中的数据。
    • 对不起,先生,我还没有在您的答案中阅读您更新的解释,现在我已经阅读了,现在我正在努力。以后我会写它是否成功。谢谢你的建议,先生。
    猜你喜欢
    • 2016-02-26
    • 2010-10-18
    • 1970-01-01
    • 2011-03-21
    • 2014-07-19
    • 2021-05-04
    • 2016-04-29
    • 2012-07-07
    • 1970-01-01
    相关资源
    最近更新 更多