• 使用google 两步验证的一个库


    <?
    /**
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     *
     * PHP Google two-factor authentication module.
     *
     * See http://www.idontplaydarts.com/2011/07/google-totp-two-factor-authentication-for-php/
     * for more details
     *
     * @author Phil
     **/
    
    class Google2FA {
    
        const keyRegeneration   = 30;   // Interval between key regeneration
        const otpLength     = 6;    // Length of the Token generated
    
        private static $lut = array(    // Lookup needed for Base32 encoding
            "A" => 0,   "B" => 1,
            "C" => 2,   "D" => 3,
            "E" => 4,   "F" => 5,
            "G" => 6,   "H" => 7,
            "I" => 8,   "J" => 9,
            "K" => 10,  "L" => 11,
            "M" => 12,  "N" => 13,
            "O" => 14,  "P" => 15,
            "Q" => 16,  "R" => 17,
            "S" => 18,  "T" => 19,
            "U" => 20,  "V" => 21,
            "W" => 22,  "X" => 23,
            "Y" => 24,  "Z" => 25,
            "2" => 26,  "3" => 27,
            "4" => 28,  "5" => 29,
            "6" => 30,  "7" => 31
        );
    
        /**
         * Generates a 16 digit secret key in base32 format
         * @return string
         **/
        public static function generate_secret_key($length = 16) {
            $b32    = "234567QWERTYUIOPASDFGHJKLZXCVBNM";
            $s  = "";
    
            for ($i = 0; $i < $length; $i++)
                $s .= $b32[rand(0,31)];
    
            return $s;
        }
    
        /**
         * Returns the current Unix Timestamp devided by the keyRegeneration
         * period.
         * @return integer
         **/
        public static function get_timestamp() {
            return floor(microtime(true)/self::keyRegeneration);
        }
    
        /**
         * Decodes a base32 string into a binary string.
         **/
        public static function base32_decode($b32) {
    
            $b32    = strtoupper($b32);
    
            if (!preg_match('/^[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]+$/', $b32, $match))
                throw new Exception('Invalid characters in the base32 string.');
    
            $l  = strlen($b32);
            $n  = 0;
            $j  = 0;
            $binary = "";
    
            for ($i = 0; $i < $l; $i++) {
    
                $n = $n << 5;               // Move buffer left by 5 to make room
                $n = $n + self::$lut[$b32[$i]];     // Add value into buffer
                $j = $j + 5;                // Keep track of number of bits in buffer
    
                if ($j >= 8) {
                    $j = $j - 8;
                    $binary .= chr(($n & (0xFF << $j)) >> $j);
                }
            }
    
            return $binary;
        }
    
        /**
         * Takes the secret key and the timestamp and returns the one time
         * password.
         *
         * @param binary $key - Secret key in binary form.
         * @param integer $counter - Timestamp as returned by get_timestamp.
         * @return string
         **/
        public static function oath_hotp($key, $counter)
        {
            if (strlen($key) < 8)
            throw new Exception('Secret key is too short. Must be at least 16 base 32 characters');
    
            $bin_counter = pack('N*', 0) . pack('N*', $counter);        // Counter must be 64-bit int
            $hash    = hash_hmac ('sha1', $bin_counter, $key, true);
    
            return str_pad(self::oath_truncate($hash), self::otpLength, '0', STR_PAD_LEFT);
        }
    
        /**
         * Verifys a user inputted key against the current timestamp. Checks $window
         * keys either side of the timestamp.
         *
         * @param string $b32seed
         * @param string $key - User specified key
         * @param integer $window
         * @param boolean $useTimeStamp
         * @return boolean
         **/
        public static function verify_key($b32seed, $key, $window = 4, $useTimeStamp = true) {
    
            $timeStamp = self::get_timestamp();
    
            if ($useTimeStamp !== true) $timeStamp = (int)$useTimeStamp;
    
            $binarySeed = self::base32_decode($b32seed);
    
            for ($ts = $timeStamp - $window; $ts <= $timeStamp + $window; $ts++)
                if (self::oath_hotp($binarySeed, $ts) == $key)
                    return true;
    
            return false;
    
        }
    
        /**
         * Extracts the OTP from the SHA1 hash.
         * @param binary $hash
         * @return integer
         **/
        public static function oath_truncate($hash)
        {
            $offset = ord($hash[19]) & 0xf;
    
            return (
                ((ord($hash[$offset+0]) & 0x7f) << 24 ) |
                ((ord($hash[$offset+1]) & 0xff) << 16 ) |
                ((ord($hash[$offset+2]) & 0xff) << 8 ) |
                (ord($hash[$offset+3]) & 0xff)
            ) % pow(10, self::otpLength);
        }
    
    
    
    }
    
    $InitalizationKey = "PEHMPSDNLXIOG65U";                 // Set the inital key
    
    $TimeStamp    = Google2FA::get_timestamp();
    $secretkey    = Google2FA::base32_decode($InitalizationKey);    // Decode it into binary
    $otp          = Google2FA::oath_hotp($secretkey, $TimeStamp);   // Get current token
    
    echo("Init key: $InitalizationKey
    ");
    echo("Timestamp: $TimeStamp
    ");
    echo("One time password: $otp
    ");
    
    // Use this to verify a key as it allows for some time drift.
    
    $result = Google2FA::verify_key($InitalizationKey, "123456");
    
    var_dump($result);
  • 相关阅读:
    EasyNVR播放HLS协议时ts文件报错404是什么问题?
    【操作步骤】EasyNVR硬件设备如何设置通电不自动启动?
    C#实现QQ接口软件QQ的HTTP接口协议探究
    第一篇随笔
    Extjs继承相关
    Montgomery乘法介绍
    中国商用密码杂凑算法标准SM3算法(数字签名)
    c语言链接动态库dll
    环、商环、整数环
    大数据挖掘技术及应用(复习重点)
  • 原文地址:https://www.cnblogs.com/linksgo2011/p/3464463.html
Copyright © 2020-2023  润新知