Hazmat HOTP
[Tokens Home][Home]
One Time Passwords (OTP) are often used in two-factor authentication systems, and where a user must enter the value. One method is HOTP (HMAC-based one-time password) uses a Hash-based Message Authentication Code (HMAC). The seed of HOTP is generated by a random key, and then the hash is defined by a counter value. The Yubikey uses a HOTP and where a counter is used to generate the required authenication value. The valid hashing algorithms used are SHA-1 (160 bit hash), SHA-256 (256-bit hash) and SHA-512 (512-bit hash), and the output is a numeric value with between 6 and 8 characters.
|
Code
Hazmat supports core cryptographical primitives for HOTP:
import os from cryptography.hazmat.primitives.twofactor.hotp import HOTP from cryptography.hazmat.primitives.hashes import SHA256, SHA1, SHA512 from cryptography.hazmat.primitives import twofactor import binascii import sys chars=6 htype=1 h=SHA256() if (len(sys.argv)>1): chars=int(sys.argv[1]) if (len(sys.argv)>2): htype=int(sys.argv[2]) if (htype==1): h=SHA256() if (htype==2): h=SHA1() if (htype==3): h=SHA512() key = os.urandom(20) hotp = HOTP(key, chars, h) print ("=== HOTP ===") print (f"Hash type:\t{h.name}") print(f"Key:\t\t{binascii.b2a_hex(key).decode()}") print() print("=== Printing the first 10 tokens ===\n") print("Count\tHash value\tVerified") for count in range(0,10): hotp_value = hotp.generate(count) print(f"[{count}]\t{hotp_value.decode()}\t",end='') rtn=hotp.verify(hotp_value, count) if (rtn==None): print(f"\t[HOTP Verified]") print("\n=== Now we will try an incorrect token ===\n") for count in range(0,3): try: hotp_value = hotp.generate(count) hotp.verify(hotp_value, count+1) except twofactor.InvalidToken: print(f"{count+1} Val:{hotp_value.decode()} Incorrect token") else: print (f"{count+1} Val:{hotp_value.decode()}")
A sample run is:
=== HOTP === Hash type: sha256 Key: 0667aad1d7894a94007b9555a3dcf282443a6ed3 === Printing the first 10 tokens === Count Hash value Verified [0] 8919396 [HOTP Verified] [1] 3555144 [HOTP Verified] [2] 3878854 [HOTP Verified] [3] 4174709 [HOTP Verified] [4] 9725032 [HOTP Verified] [5] 7252328 [HOTP Verified] [6] 8383791 [HOTP Verified] [7] 6755309 [HOTP Verified] [8] 7111829 [HOTP Verified] [9] 4178897 [HOTP Verified] === Now we will try an incorrect token === 1 Val:8919396 Incorrect token 2 Val:3555144 Incorrect token 3 Val:3878854 Incorrect token