Hazmat HOTP
[Hazmat 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 ("Hash type: ",h.name) print(f"Key: ",binascii.b2a_hex(key)) print() print("=== Printing the first 10 tokens ===\n") for count in range(0,10): try: hotp_value = hotp.generate(count) hotp.verify(hotp_value, count) except twofactor.InvalidToken: print("Incorrect token") else: print (f"{count} Val:{hotp_value.decode()}") 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: b'8c36ba8a152548707d640510fec32a6aa59228f9' === Printing the first 10 tokens === 0 Val:442712 1 Val:222337 2 Val:120850 3 Val:495481 4 Val:799130 5 Val:953867 6 Val:017365 7 Val:276423 8 Val:686418 9 Val:650831 === Now we will try an incorrect token === 1 Val:442712 Incorrect token 2 Val:222337 Incorrect token 3 Val:120850 Incorrect token