Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用hash_hmac()在PHP中实现TOTP的问题_Php_Hmacsha1_Totp - Fatal编程技术网

使用hash_hmac()在PHP中实现TOTP的问题

使用hash_hmac()在PHP中实现TOTP的问题,php,hmacsha1,totp,Php,Hmacsha1,Totp,我试图在PHP中实现TOTP,我得到了一个六位数的代码,但它与我的Authenticator应用程序中的代码不匹配。我能够专注于最有可能与hash_hmac的输出相关的问题,因为我测试了在RFC文档中的示例上生成hash之后发生的所有位移位,它生成了预期的输出。我现在的问题是:我做错了什么?我是否将格式错误的输入传递给hash_hmac?我在这里真是不知所措 <?php class TOTP { function __construct ($d, $k) {

我试图在PHP中实现TOTP,我得到了一个六位数的代码,但它与我的Authenticator应用程序中的代码不匹配。我能够专注于最有可能与hash_hmac的输出相关的问题,因为我测试了在RFC文档中的示例上生成hash之后发生的所有位移位,它生成了预期的输出。我现在的问题是:我做错了什么?我是否将格式错误的输入传递给hash_hmac?我在这里真是不知所措

<?php

class TOTP
{
    function __construct ($d, $k)
    {
        $this->digits = $d;
        $this->secret = $k;
        $this->ival   = 30;
    }


    private function int2bytes ($n)
    {
        $bytes = array();

        for ($i = 7; $i >= 0; $i--) {
            $bytes[] = ($n >> ($i * 8)) & 0xff;
        }

        return pack("C*", ...$bytes);
    }


    function hotp ($d, $k, $c)
    {
        // @$d the number of digits
        // @$k the shared secret
        // @$c an integer counter

        $hmac  = hash_hmac("sha1", $this->int2bytes($c), $k);
        $hex   = str_split($hmac, 2);
        $bytes = array();

        for ($i = 0; $i < count($hex); $i++) {
            $bytes[] = hexdec($hex[$i]);
        }

        $offset  = $bytes[19] & 0xf;
        $bincode =
            ($bytes[$offset] & 0x7f) << 24 |
            ($bytes[$offset + 1] & 0xff) << 16|
            ($bytes[$offset + 2] & 0xff) << 8 |
            $bytes[$offset + 3] & 0xff;

        $hotp = strval($bincode % pow(10, $d));

        while (strlen($hotp) < $d) {
            $hotp = "0$hotp";
        }


        return $hotp;
    }


    public function get ()
    {
        $counter = floor(time() / $this->ival);

        return $this->hotp($this->digits, $this->secret, $counter);
    }
}

?>

请添加一些带有输入和输出的测试。输出应为预期输出和有效输出。感谢他们来到主岗位!
unix time: 1584041829
output:    79 06 09
expected:  91 97 63

unix time: 1584041867
output:    76 89 74
expected:  70 54 64

unix time: 1584041918
output:    46 57 96
expected:  52 96 15