請選擇 進入手機版 | 繼續訪問電腦版

微剋多資訊

 找回密碼
 註冊

Sign in with google

You know.

搜索
回覆 1則 瀏覽 301篇

[提問] (HOTP) Authenticator 寫法請教

簽到天數: 176

該用戶今日未簽到

發表於 2018-11-6 00:01 | 顯示全部樓層 |閱讀模式
本帖最後由 gary8349 於 2018-11-6 00:04 編輯

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

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


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


  4. Dim $overSec = Null, $a, $n

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

  6. ;每30秒一次的時間戳
  7. For $n = 0 To 29 ;;判斷是否為30可整除,否則減少至可整除
  8.         If _MathCheckDiv($unixTime,30) = 2 Then
  9.                 $overSec = 29 - $n ;;30秒一次的金鑰 剩餘時間(GUI顯示用)
  10.                 ExitLoop(1)
  11.         Else
  12.                 $a = $unixTime - $n
  13.                 If _MathCheckDiv($a,30) = 2 Then
  14.                         $unixTime = $a
  15.                         $overSec = 29 - $n
  16.                         ExitLoop(1)
  17.                 EndIf
  18.         EndIf
  19. Next
  20. ;;MsgBox(0,0,$unixTime)

  21. Dim $counter = Int($unixTime) / 30
  22. Dim $key = _HMAC_SHA1('JBSWY3DPEHPK3PXP',$counter)
  23. Dim $Offset = StringRight($key,1) ;;---取16進制最後一字(偏移量)
  24. If StringRegExp($Offset,'[a-fA-F]',0) = 1 Then
  25.         If $Offset = 'A' Then $Offset = '10'
  26.         If $Offset = 'B' Then $Offset = '11'
  27.         If $Offset = 'C' Then $Offset = '12'
  28.         If $Offset = 'D' Then $Offset = '13'
  29.         If $Offset = 'E' Then $Offset = '14'
  30.         If $Offset = 'F' Then $Offset = '15'
  31. EndIf
  32. $m = StringSplit($key,'x')
  33. $Sbits = StringMid($m[2],$Offset,8) ;;---16進制

  34. ;;---16轉為10進制
  35. Dim $s = 7
  36. Dim $tenVal = Null, $num = Null, $num2 = Null
  37. For $i = 0 to 7
  38.         $num = StringMid ($Sbits,$i+1,1)
  39.         If StringRegExp($num,'[a-fA-F]',0) = 1 Then
  40.                 If $num = 'A' Then $num = '10'
  41.                 If $num = 'B' Then $num = '11'
  42.                 If $num = 'C' Then $num = '12'
  43.                 If $num = 'D' Then $num = '13'
  44.                 If $num = 'E' Then $num = '14'
  45.                 If $num = 'F' Then $num = '15'
  46.         EndIf
  47.         $num2 = $num * 16 ^ $s
  48.         $s -= 1
  49.         $tenVal += $num2 ;;10進制
  50. Next

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

  53. ;;---補齊6位數
  54. If StringLen($OTP) < 6 Then
  55.         $a = 6 - StringLen($OTP)
  56.         If $a = 6 Then $OTP = '000000' & Mod($tenVal,10^6)
  57.         If $a = 5 Then $OTP = '00000' & Mod($tenVal,10^6)
  58.         If $a = 4 Then $OTP = '0000' & Mod($tenVal,10^6)
  59.         If $a = 3 Then $OTP = '000' & Mod($tenVal,10^6)
  60.         If $a = 2 Then $OTP = '00' & Mod($tenVal,10^6)
  61.         If $a = 1 Then $OTP = '0' & Mod($tenVal,10^6)
  62. EndIf

  63. MsgBox(64,'','$key: ' & $key & @CRLF & '$Sbits: ' & $Sbits & @CRLF & '$tenVal: ' & $tenVal & @CRLF & '$OTP: ' & $OTP)
複製代碼

該用戶從未簽到

發表於 2018-11-7 14:25 | 顯示全部樓層
以前用 JS 寫過,但已經忘得差不多了

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

從 1970/01/01 00:00:00 到當下的秒數

使用道具

您需要登入後才可以回帖 登入 | 註冊

本版積分規則

Discuz! X

© 2009-2017 Microduo

快速回覆 返回頂部 返回列表