找回密码  加入

AUTOIT CN

搜索
查看: 141|回复: 1

[AU3基础] (HOTP) Authenticator 寫法請教

[复制链接]
发表于 2018-11-4 21:45:54 | 显示全部楼层 |阅读模式
本帖最后由 w60711 于 2018-11-6 00:03 编辑

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-5 23:48:13 | 显示全部楼层
本帖最后由 w60711 于 2018-11-6 19:52 编辑

https://www.autoitscript.com/for ... tor-implementation /
以下撷取内容

请求大神帮忙,实在不懂意思>>> ConsoleWrite(_GenerateTOTP("JBSWY3DPEHPK3PXP") & @CRLF)
还有上面我参考网路上解说写的TOTP,但结果不一样,也请帮忙解惑,感谢~

Google Authenticator Implementation

I've had this one rolling around my brain for a while now. And while I can't take credit for much of anything at this point since it's just implementation, here's a framework for Time-based One-Time Password authentication, ie Google Authenticator. I've added links in all the places where I've harvested code. I'm planning on building this into an actual authenticator app, so this is just step one.
As always, thanks to everyone whose code contributed.

Example: Use the test vectors function to test HOTP mode, or visit http://gauth.apps.gbraad.nl/ for a live test site. The default account uses "JBSWY3DPEHPK3PXP" as the key ( https://code.google.com/p/google-authenticator/wiki/KeyUriFormat ).

ConsoleWrite(_GenerateTOTP("JBSWY3DPEHPK3PXP") & @CRLF))

_GAuth.au3
  1. #include-once
  2. #include <_HMAC.au3>
  3. #include <Date.au3>

  4. ;; http://tools.ietf.org/html/rfc6238
  5. Func _GenerateTOTP($key, $keyIsBase32 = True, $time = Default, $period = 30, $digits = 6)
  6.     Local $DIGITS_POWER[9] = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000]
  7.     ; time is some number of seconds
  8.     If $time = Default Then $time = _GetUnixTimeUTC()
  9.     $time = StringFormat("%016X", Floor($time / $period))
  10.     If $keyIsBase32 Then
  11.         $key = _Base32ToHex($key, True) ; return binary
  12.     Else
  13.         $key = StringToBinary($key)
  14.     EndIf
  15.     ; HMAC function expects binary arguments
  16.     Local $hash = _HMAC_SHA1($key, Binary("0x" & $time))
  17.     Local $offset = BitAND(BinaryMid($hash, BinaryLen($hash), 1), 0xf)
  18.     Local $otp = BitOR(BitShift(BitAND(BinaryMid($hash, $offset + 1, 1), 0x7f), -24), _
  19.             BitShift(BitAND(BinaryMid($hash, $offset + 2, 1), 0xff), -16), _
  20.             BitShift(BitAND(BinaryMid($hash, $offset + 3, 1), 0xff), -8), _
  21.             BitAND(BinaryMid($hash, $offset + 4, 1), 0xff) _
  22.             )
  23.     $otp = Mod($otp, $DIGITS_POWER[$digits])
  24.     Return StringFormat("%0" & $digits & "i", $otp)
  25. EndFunc

  26. ;; http://www.autoitscript.com/forum/topic/153617-seconds-since-epoch-aka-unix-timestamp/
  27. Func _GetUnixTimeUTC()
  28.     ; returns number of seconds since EPOCH in UTC
  29.     Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation()
  30.     Local $utcTime = ""
  31.     Local $sDate = _NowCalc()
  32.     If $aSysTimeInfo[0] = 2 Then
  33.         $utcTime = _DateAdd('n', $aSysTimeInfo[1] + $aSysTimeInfo[7], $sDate)
  34.     Else
  35.         $utcTime = _DateAdd('n', $aSysTimeInfo[1], $sDate)
  36.     EndIf
  37.     Return _DateDiff('s', "1970/01/01 00:00:00", $utcTime)
  38. EndFunc

  39. ;; http://tomeko.net/online_tools/base32.php?lang=en
  40. Func _Base32ToHex($sInput, $returnBinary = False)
  41.     $sInput = StringRegExpReplace(StringUpper($sInput), "[^A-Z2-7]", "")
  42.     Local $key = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
  43.     Local $buffer = 0, $bitsLeft = 0, $i = 0, $count = 0, $output = "", $val
  44.     While $i < StringLen($sInput)
  45.         $val = StringInStr($key, StringMid($sInput, $i + 1, 1)) - 1 ; StringInStr returns 1 as 1st position
  46.         If $val >=0 And $val < 32 Then
  47.             $buffer = BitOR(BitShift($buffer, -5), $val)
  48.             $bitsLeft += 5
  49.             If $bitsLeft >= 8 Then
  50.                 $output &= Chr(BitAND(BitShift($buffer, $bitsLeft - 8), 0xFF))
  51.                 $bitsLeft -= 8
  52.             EndIf
  53.         EndIf
  54.         $i += 1
  55.     WEnd
  56.     If $bitsLeft > 0 Then
  57.         $buffer = BitShift($buffer, -5)
  58.         $output &= Chr(BitAND(BitShift($buffer, $bitsLeft - 3), 0xFF))
  59.     EndIf
  60.     If $returnBinary Then
  61.         Return StringToBinary($output)
  62.     Else
  63.         Return $output
  64.     EndIf
  65. EndFunc

  66. #cs
  67. Alternate base32 to hex functions
  68. Func _b32toh($input)
  69.     $input = StringRegExpReplace(StringUpper($input), "[^A-Z2-7]", "")
  70.     Local $ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
  71.     Local $bits = "", $hex = "", $val, $i
  72.     For $i = 0 To StringLen($input) - 1
  73.         $val = StringInStr($ch, StringMid($input, $i + 1, 1)) - 1
  74.         $bits &= StringFormat("%05s", _itob($val))
  75.     Next
  76.     $i = 0
  77.     Local $chunk
  78.     While ($i + 4) <= StringLen($bits)
  79.         $chunk = StringMid($bits, $i + 1, 4)
  80.         $hex &= StringFormat("%X", _btoi($chunk))
  81.         $i += 4
  82.     WEnd
  83.     Return $hex
  84. EndFunc

  85. ; int to binary (0's and 1's) string
  86. Func _itob($int)
  87.     Local $o = ""
  88.     While $int
  89.         $o = BitAND($int, 1) & $o
  90.         $int = BitShift($int, 1)
  91.     WEnd
  92.     Return $o
  93. EndFunc

  94. ; binary (0's and 1's) string to int
  95. Func _btoi($b)
  96.     Local $p = 0, $o = 0
  97.     For $i = StringLen($b) To 1 Step -1
  98.         $o += (2 ^ $p) * Number(StringMid($b, $i, 1))
  99.         $p += 1
  100.     Next
  101.     Return $o
  102. EndFunc
  103. #ce

  104. Func _TOTPTestVectors()
  105. #cs
  106.    Test vectors operate in HOTP mode.

  107.    The test token shared secret uses the ASCII string value
  108.    "12345678901234567890".  With Time Step X = 30, and the Unix epoch as
  109.    the initial value to count time steps, where T0 = 0, the TOTP
  110.    algorithm will display the following values for specified modes and
  111.    timestamps.

  112.   +-------------+--------------+------------------+----------+--------+
  113.   |  Time (sec) |   UTC Time   | Value of T (hex) |   TOTP   |  Mode  |
  114.   +-------------+--------------+------------------+----------+--------+
  115.   |      59     |  1970-01-01  | 0000000000000001 | 94287082 |  SHA1  |
  116.   |             |   00:00:59   |                  |          |        |
  117.   |  1111111109 |  2005-03-18  | 00000000023523EC | 07081804 |  SHA1  |
  118.   |             |   01:58:29   |                  |          |        |
  119.   |  1111111111 |  2005-03-18  | 00000000023523ED | 14050471 |  SHA1  |
  120.   |             |   01:58:31   |                  |          |        |
  121.   |  1234567890 |  2009-02-13  | 000000000273EF07 | 89005924 |  SHA1  |
  122.   |             |   23:31:30   |                  |          |        |
  123.   |  2000000000 |  2033-05-18  | 0000000003F940AA | 69279037 |  SHA1  |
  124.   |             |   03:33:20   |                  |          |        |
  125.   | 20000000000 |  2603-10-11  | 0000000027BC86AA | 65353130 |  SHA1  |
  126.   |             |   11:33:20   |                  |          |        |
  127.   +-------------+--------------+------------------+----------+--------+
  128. #ce
  129.     Local $times[6] = [59, 1111111109, 1111111111, 1234567890, 2000000000, 20000000000]
  130.     For $i = 0 To 5
  131.         ConsoleWrite(StringFormat("%016X", Floor($times[$i] / 30)) & " : " & _
  132.             _GenerateTOTP("12345678901234567890", False, $times[$i], 30, 8) & @CRLF)
  133.     Next
  134. EndFunc
复制代码


_HMAC.au3
  1. #include-once
  2. #include <Crypt.au3>

  3. ;; http://www.autoitscript.com/forum/topic/145556-solved-hmac-sha1/?p=1028830
  4. Func _HMAC_SHA1($key, $message)
  5.     If Not IsBinary($key) Then $key = Binary($key)
  6.     If Not IsBinary($message) Then $message = Binary($message)
  7.     Local $blocksize = 64
  8.     Local $a_opad[$blocksize], $a_ipad[$blocksize]
  9.     Local Const $oconst = 0x5C, $iconst = 0x36
  10.     Local $opad = Binary(''), $ipad = Binary('')
  11.     If BinaryLen($key) > $blocksize Then $key = _Crypt_HashData($key, $CALG_SHA1)
  12.     For $i = 1 To BinaryLen($key)
  13.         $a_ipad[$i-1] = Number(BinaryMid($key, $i, 1))
  14.         $a_opad[$i-1] = Number(BinaryMid($key, $i, 1))
  15.     Next
  16.     For $i = 0 To $blocksize - 1
  17.         $a_opad[$i] = BitXOR($a_opad[$i], $oconst)
  18.         $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst)
  19.     Next
  20.     For $i = 0 To $blocksize - 1
  21.         $ipad &= Binary('0x' & Hex($a_ipad[$i], 2))
  22.         $opad &= Binary('0x' & Hex($a_opad[$i], 2))
  23.     Next
  24.     Return _Crypt_HashData($opad & _Crypt_HashData($ipad & $message, $CALG_SHA1), $CALG_SHA1)
  25. EndFunc

  26. Func _HMAC_MD5($key, $message)
  27.     If Not IsBinary($key) Then $key = Binary($key)
  28.     If Not IsBinary($message) Then $message = Binary($message)
  29.     Local $blocksize = 64
  30.     Local $a_opad[$blocksize], $a_ipad[$blocksize]
  31.     Local Const $oconst = 0x5C, $iconst = 0x36
  32.     Local $opad = Binary(''), $ipad = Binary('')
  33.     If BinaryLen($key) > $blocksize Then $key = _Crypt_HashData($key, $CALG_MD5)
  34.     For $i = 1 To BinaryLen($key)
  35.         $a_ipad[$i-1] = Number(BinaryMid($key, $i, 1))
  36.         $a_opad[$i-1] = Number(BinaryMid($key, $i, 1))
  37.     Next
  38.     For $i = 0 To $blocksize - 1
  39.         $a_opad[$i] = BitXOR($a_opad[$i], $oconst)
  40.         $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst)
  41.     Next
  42.     For $i = 0 To $blocksize - 1
  43.         $ipad &= Binary('0x' & Hex($a_ipad[$i], 2))
  44.         $opad &= Binary('0x' & Hex($a_opad[$i], 2))
  45.     Next
  46.     Return _Crypt_HashData($opad & _Crypt_HashData($ipad & $message, $CALG_MD5), $CALG_MD5)
  47. <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">ENDFUNC</font></font>
复制代码


您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|小黑屋|手机版|AUTOIT CN ( 鲁ICP备15028933号-3 )谷歌 百度

GMT+8, 2018-11-13 23:38 , Processed in 0.096987 second(s), 14 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表