ホームページ > バックエンド開発 > PHPチュートリアル > PHP で OATH 動的パスワード アルゴリズムを実装するためのサンプル コードの共有

PHP で OATH 動的パスワード アルゴリズムを実装するためのサンプル コードの共有

黄舟
リリース: 2023-03-06 20:24:01
オリジナル
2133 人が閲覧しました

OATH動的パスワードアルゴリズムを実装したPHPのサンプルコード共有

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

<?PHP 

/**

 * 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(&#39;/^[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]+$/&#39;, $b32, $match)) 

            throw new Exception(&#39;Invalid characters in the base32 string.&#39;); 

   

        $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(&#39;Secret key is too short. Must be at least 16 base 32 characters&#39;); 

   

        $bin_counter = pack(&#39;N*&#39;, 0) . pack(&#39;N*&#39;, $counter);        // Counter must be 64-bit int 

        $hash      = hash_hmac (&#39;sha1&#39;, $bin_counter, $key, true); 

   

        return str_pad(self::oath_truncate($hash), self::otpLength, &#39;0&#39;, 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 = "LFLFMU2SGVCUIUCZKBMEKRKLIQ";                    // 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\n"); 

echo("Timestamp: $TimeStamp\n"); 

echo("One time password: $otp\n"); 

   

// Use this to verify a key as it allows for some time drift. 

   

$result = Google2FA::verify_key($InitalizationKey, "123456"); 

   

var_dump($result); 

   

?>

ログイン後にコピー

上記の内容は、oath.phpとして保存されます:

1. コマンドを実行します。行: php.exe oath.php

パスの問題については誰もが知っています

2. Web ディレクトリにデプロイされ、Web ページからアクセスします

例: http://localhost/oath.php

以上がPHP で OATH 動的パスワード アルゴリズムを実装するためのサンプル コードの共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート