【问题标题】:PHP one-time password?PHP一次性密码?
【发布时间】:2013-10-06 06:28:57
【问题描述】:

我一直在努力学习如何使用 HOTPAndroid Google Authenication 的基于计数器的 HOTP 代码)。 我找到了这段代码,它能够在服务器和客户端(移动应用程序)之间共享一个密钥。

<?php
function oath_hotp($key,$counter) {

   // Convert to padded binary string
   $data = pack ('C*', $counter);
   $data = str_pad($data,8,chr(0),STR_PAD_LEFT);

   // HMAC
   return hash_hmac('sha1',$data,$key);
}

function oath_truncate($hash, $length = 6) {

   // Convert to dec
   foreach(str_split($hash,2) as $hex) {
      $hmac_result[]=hexdec($hex);
   }

   // Find offset
   $offset = $hmac_result[19] & 0xf;

   // Algorithm from RFC
   return (
         (($hmac_result[$offset+0] & 0x7f) << 24 ) |
         (($hmac_result[$offset+1] & 0xff) << 16 ) |
         (($hmac_result[$offset+2] & 0xff) << 8 ) |
         ($hmac_result[$offset+3] & 0xff)
         ) % pow(10,$length);
}

print "<pre>";
print "Compare results with:";
print " http://tools.ietf.org/html/draft-mraihi-oath-hmac-otp-04\n";
print "Count\tHash\t\t\t\t\t\tPin\n";
for($i=0;$i<10;$i++){
   print $i."\t".($a=oath_hotp("mysecretvalue",$i));
   print "\t".oath_truncate($a)."\n";
}
?>

这个输出如下 -

Compare results with: http://tools.ietf.org/html/draft-mraihi-oath-hmac-otp-04
Count                   Hash                      Pin
0   f25e6c58cc7a2dfedae7eb48a1bff891aa0c0189    472801
1   b52adf13022511f08740566fb44c0b267d7c2604    983856
2   3c693c66f6e04178943dc9badc0dd41318dbc7f7    981065
3   1225cf508043a59fe2e39e335ff5f3e5795131ba    683381
4   21a9756e8de58df5e10c9292e0147823ba03539b    675192
5   7339c3496cebdaf3a035eaba888f61d8c19d8cf9    575624
6   c7c03ce2174f144a329664d35cc90e70a3686596    406934
7   431a75f26b9950f0206911667f3a2ed7fdfc43c7    172241
8   81e05a2d9e060a25f515b1e53170dce4daad5cc7    818865
9   ff2068918dc53db45a0c338d8de99419cf3cb571    723917

现在我的问题是我无法管理上述代码在客户端和服务器端都正常工作。我使用了相同的密钥print $i."\t".($a=oath_hotp("**mysecretvalue**",$i)); 输出完全不同。请注意,这是基于计数器的,这意味着没有像 TOTP 这样的时间同步。

我已经在我的安卓手机和服务器端仔细检查了我的密码。有什么问题?请注意,我对 PHP 安全性并不十分熟悉。因此,如果上述方法不适用于 Google 的身份验证,请为我提供一个开始的地方。

谢谢

【问题讨论】:

    标签: php android authentication hash one-time-password


    【解决方案1】:

    Google Authenticator 将输入密码作为 RFC 3548 base32 (https://code.google.com/p/google-authenticator/),而您使用的是 ASCII 密码。

    您拥有的 php 代码很好(您可以通过在 ASCII 中传递“12345678901234567890”的秘密并对照http://www.ietf.org/rfc/rfc4226.txt 的附录 D 检查它来查看)。

    您需要做的是将您输入 Google 身份验证器的密码从 base32 转换为 ASCII。

    您可以使用来自github https://github.com/devicenull/PHP-Google-Authenticator/blob/master/base32.php 的这个实用程序类base32 为您进行转换,然后添加:

    include_once "base32.php";
    $keyToTest = "mysecretvalue";
    
    $b = new Base32(Base32::csRFC3548);
    $keyToTest = $b->toString($keyToTest);
    
    for($i=0;$i<10;$i++){
       print $i."\t".($a=oath_hotp($keyToTest,$i));
       print "\t".oath_truncate($a)."\n";
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-15
      • 1970-01-01
      • 1970-01-01
      • 2020-09-29
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      相关资源
      最近更新 更多