实施 TOTP 8086 汇编 (TASM)
Implementing TOTP 8086 Assembly (TASM)
我正在尝试在 8086 汇编上实现 TOTP。 return unix time/30 和 HMAC-SHA1 的程序运行良好(已检查)。
我使用的密钥“0000000000”等于 0x30303030303030303030(base32 中的 GAYDAMBQGAYDAMBQ),我得到的结果与 Google Authenticator 应用程序不同。
这是我的代码:
proc GoogleAuthenticator
call EpochTimeDiv30 ;get epoch time in seconds/30 in dx:ax
xchg dh, dl ;we need it to be big endian in the memory
xchg ah, al
;---------------------HMAC-SHA1 preparation------------------
mov [word HmacMsg], dx
mov [word HmacMsg+2], ax ;msg is epoch time
mov [HmacMsgLen], 4 ;msg length is 4bytes
mov [HKeyLen], 10 ;key length is 10bytes
lea bx, [HmacMsg]
mov [HmacMsgOffset], bx ;put the offset of the msg
call HMAC_SHA1 ;Key is already in Key var
;Now the result is in msgHash (result is big-endian)
mov al, [msgHash+19] ;last byte of hashed msg
and al, 0Fh ;we need only the last nibble
xor ah, ah
mov si, ax
mov dx, [word msgHash+si] ;get offset, offset+1
mov ax, [word msgHash+si+2] ;get offfset+2, offset+3
xchg dh, dl ;back to big endian
xchg ah, al ;back to big endian
and dh, 7Fh ;removing the most significant bit(MSB)
Mod32 0Fh, 4240h ;dx:ax modulo 1,000,000
ret
endp GoogleAuthenticator
编辑:
我尝试实现的算法:
function GoogleAuthenticatorCode(string secret)
key := 5B5E7MMX344QRHYO
message := floor(current Unix time / 30)
hash := HMAC-SHA1(key, message)
offset := last nibble of hash
truncatedHash := hash[offset..offset+3] //4 bytes starting at the offset
Set the first bit of truncatedHash to zero //remove the most significant bit
code := truncatedHash mod 1000000
pad code with 0 from the left until length of code is 6
return code
我找到问题了。
消息应为 8 个字节长。
这是工作代码:
proc GoogleAuthenticator
call EpochTimeDiv30 ;get epoch time in seconds/30 in dx:ax
xchg dh, dl ;we need it to be big endian in the memory
xchg ah, al
;---------------------HMAC-SHA1 preparation------------------
mov [word HmacMsg], 0
mov [word HmacMsg+2], 0
mov [word HmacMsg+4], dx
mov [word HmacMsg+6], ax ;msg is epoch time
mov [HmacMsgLen], 8 ;msg length is 4bytes
mov [HKeyLen], 10 ;key length is 10bytes
lea bx, [HmacMsg]
mov [HmacMsgOffset], bx ;put the offset of the msg
call HMAC_SHA1 ;Key is already in Key var
;Now the result is in msgHash (result is big-endian)
mov al, [msgHash+19] ;last byte of hashed msg
and al, 0Fh ;we need only the last nibble
xor ah, ah
mov si, ax
mov dx, [word msgHash+si] ;get offset, offset+1
mov ax, [word msgHash+si+2] ;get offfset+2, offset+3
xchg dh, dl ;back to big endian
xchg ah, al ;back to big endian
and dh, 7Fh ;removing the most significant bit(MSB)
Mod32 0Fh, 4240h ;dx:ax modulo 1,000,000
ret
endp GoogleAuthenticator
我正在尝试在 8086 汇编上实现 TOTP。 return unix time/30 和 HMAC-SHA1 的程序运行良好(已检查)。 我使用的密钥“0000000000”等于 0x30303030303030303030(base32 中的 GAYDAMBQGAYDAMBQ),我得到的结果与 Google Authenticator 应用程序不同。 这是我的代码:
proc GoogleAuthenticator
call EpochTimeDiv30 ;get epoch time in seconds/30 in dx:ax
xchg dh, dl ;we need it to be big endian in the memory
xchg ah, al
;---------------------HMAC-SHA1 preparation------------------
mov [word HmacMsg], dx
mov [word HmacMsg+2], ax ;msg is epoch time
mov [HmacMsgLen], 4 ;msg length is 4bytes
mov [HKeyLen], 10 ;key length is 10bytes
lea bx, [HmacMsg]
mov [HmacMsgOffset], bx ;put the offset of the msg
call HMAC_SHA1 ;Key is already in Key var
;Now the result is in msgHash (result is big-endian)
mov al, [msgHash+19] ;last byte of hashed msg
and al, 0Fh ;we need only the last nibble
xor ah, ah
mov si, ax
mov dx, [word msgHash+si] ;get offset, offset+1
mov ax, [word msgHash+si+2] ;get offfset+2, offset+3
xchg dh, dl ;back to big endian
xchg ah, al ;back to big endian
and dh, 7Fh ;removing the most significant bit(MSB)
Mod32 0Fh, 4240h ;dx:ax modulo 1,000,000
ret
endp GoogleAuthenticator
编辑: 我尝试实现的算法:
function GoogleAuthenticatorCode(string secret)
key := 5B5E7MMX344QRHYO
message := floor(current Unix time / 30)
hash := HMAC-SHA1(key, message)
offset := last nibble of hash
truncatedHash := hash[offset..offset+3] //4 bytes starting at the offset
Set the first bit of truncatedHash to zero //remove the most significant bit
code := truncatedHash mod 1000000
pad code with 0 from the left until length of code is 6
return code
我找到问题了。 消息应为 8 个字节长。 这是工作代码:
proc GoogleAuthenticator
call EpochTimeDiv30 ;get epoch time in seconds/30 in dx:ax
xchg dh, dl ;we need it to be big endian in the memory
xchg ah, al
;---------------------HMAC-SHA1 preparation------------------
mov [word HmacMsg], 0
mov [word HmacMsg+2], 0
mov [word HmacMsg+4], dx
mov [word HmacMsg+6], ax ;msg is epoch time
mov [HmacMsgLen], 8 ;msg length is 4bytes
mov [HKeyLen], 10 ;key length is 10bytes
lea bx, [HmacMsg]
mov [HmacMsgOffset], bx ;put the offset of the msg
call HMAC_SHA1 ;Key is already in Key var
;Now the result is in msgHash (result is big-endian)
mov al, [msgHash+19] ;last byte of hashed msg
and al, 0Fh ;we need only the last nibble
xor ah, ah
mov si, ax
mov dx, [word msgHash+si] ;get offset, offset+1
mov ax, [word msgHash+si+2] ;get offfset+2, offset+3
xchg dh, dl ;back to big endian
xchg ah, al ;back to big endian
and dh, 7Fh ;removing the most significant bit(MSB)
Mod32 0Fh, 4240h ;dx:ax modulo 1,000,000
ret
endp GoogleAuthenticator