gary8349 發表於 2018-11-6 00:01

(HOTP) Authenticator 寫法請教

本帖最後由 gary8349 於 2018-11-6 00:04 編輯

https://www.autoitscript.com/for ... tor-implementation/
在下不才,在網上找到這個UDF,但還是不懂寫法

要如何才能生成 6位數密鑰,每30秒更換一次
其公式如何?
懇請先進們解惑,感謝~


以下我參考 網站 寫的code和 此網站 的結果不相符...請問是哪邊要修改?#include <_HMAC.au3>
#include <_GAuth.au3>
#include <math.au3>


Dim $overSec = Null, $a, $n

Dim $unixTime = _GetUnixTimeUTC() + 28800 ;;UTC+8 ?

;每30秒一次的時間戳
For $n = 0 To 29 ;;判斷是否為30可整除,否則減少至可整除
      If _MathCheckDiv($unixTime,30) = 2 Then
                $overSec = 29 - $n ;;30秒一次的金鑰 剩餘時間(GUI顯示用)
                ExitLoop(1)
      Else
                $a = $unixTime - $n
                If _MathCheckDiv($a,30) = 2 Then
                        $unixTime = $a
                        $overSec = 29 - $n
                        ExitLoop(1)
                EndIf
      EndIf
Next
;;MsgBox(0,0,$unixTime)

Dim $counter = Int($unixTime) / 30
Dim $key = _HMAC_SHA1('JBSWY3DPEHPK3PXP',$counter)
Dim $Offset = StringRight($key,1) ;;---取16進制最後一字(偏移量)
If StringRegExp($Offset,'',0) = 1 Then
      If $Offset = 'A' Then $Offset = '10'
      If $Offset = 'B' Then $Offset = '11'
      If $Offset = 'C' Then $Offset = '12'
      If $Offset = 'D' Then $Offset = '13'
      If $Offset = 'E' Then $Offset = '14'
      If $Offset = 'F' Then $Offset = '15'
EndIf
$m = StringSplit($key,'x')
$Sbits = StringMid($m,$Offset,8) ;;---16進制

;;---16轉為10進制
Dim $s = 7
Dim $tenVal = Null, $num = Null, $num2 = Null
For $i = 0 to 7
      $num = StringMid ($Sbits,$i+1,1)
      If StringRegExp($num,'',0) = 1 Then
                If $num = 'A' Then $num = '10'
                If $num = 'B' Then $num = '11'
                If $num = 'C' Then $num = '12'
                If $num = 'D' Then $num = '13'
                If $num = 'E' Then $num = '14'
                If $num = 'F' Then $num = '15'
      EndIf
      $num2 = $num * 16 ^ $s
      $s -= 1
      $tenVal += $num2 ;;10進制
Next

$Digit = 6 ;;6位數金鑰
$OTP = Mod($tenVal,10^$Digit)

;;---補齊6位數
If StringLen($OTP) < 6 Then
      $a = 6 - StringLen($OTP)
      If $a = 6 Then $OTP = '000000' & Mod($tenVal,10^6)
      If $a = 5 Then $OTP = '00000' & Mod($tenVal,10^6)
      If $a = 4 Then $OTP = '0000' & Mod($tenVal,10^6)
      If $a = 3 Then $OTP = '000' & Mod($tenVal,10^6)
      If $a = 2 Then $OTP = '00' & Mod($tenVal,10^6)
      If $a = 1 Then $OTP = '0' & Mod($tenVal,10^6)
EndIf

MsgBox(64,'','$key: ' & $key & @CRLF & '$Sbits: ' & $Sbits & @CRLF & '$tenVal: ' & $tenVal & @CRLF & '$OTP: ' & $OTP)

ad6543210 發表於 2018-11-7 14:25

以前用 JS 寫過,但已經忘得差不多了

只看得出一個地方
時間戳的部分不用加八小時,因為那是一個固定數字

從 1970/01/01 00:00:00 到當下的秒數
頁: [1]
查看完整版本: (HOTP) Authenticator 寫法請教