def test_verify(self, backend, params): secret = params["secret"] counter = int(params["counter"]) hotp_value = params["hotp"] hotp = HOTP(secret, 6, SHA1(), backend) hotp.verify(hotp_value, counter)
def generate_htop(length=6, salt=0): hotp = HOTP(key, length, SHA1(), backend=default_backend()) hotp_value = hotp.generate(salt) # hotp.verify(hotp_value, 0) return hotp_value.decode()
def add_otptoken(host, owner, *, otptype="hotp", digits=6, algo="sha1"): args = [ "ipa", "otptoken-add", "--owner", owner, "--type", otptype, "--digits", str(digits), "--algo", algo, "--no-qrcode", ] result = host.run_command(args) otpuid = re.search(r"Unique ID:\s*([a-z0-9-]*)\s+", result.stdout_text).group(1) otpuristr = re.search(r"URI:\s*(.*)\s+", result.stdout_text).group(1) otpuri = urlparse(otpuristr) assert otpuri.netloc == otptype query = parse_qs(otpuri.query) assert query["algorithm"][0] == algo.upper() assert query["digits"][0] == str(digits) key = base64.b32decode(query["secret"][0]) assert len(key) == 35 hashcls = getattr(hashes, algo.upper()) if otptype == "hotp": return otpuid, HOTP(key, digits, hashcls(), default_backend()) else: period = int(query["period"][0]) return otpuid, TOTP(key, digits, hashcls(), period, default_backend())
def verify_hotp_code(secret, code, counter): """ Validate a Google authenticator compatible HOTP code Args: secret: 16 character base32 secret code: 6 digit code that expires in 30 seconds counter: matching integer value Return: Counter value if validation successful or None """ if isinstance(secret, unicode): secret = secret.encode('utf-8') if isinstance(code, unicode): code = code.encode('utf-8') try: key = base64.b32decode(secret) hotp = HOTP(key, 6, SHA1(), backend=default_backend(), enforce_key_length=False) for count in range(counter, counter + 3): try: hotp.verify(code, count) return count except InvalidToken: pass except (ValueError, TypeError): pass return None
def test_invalid_backend(): secret = b"12345678901234567890" pretend_backend = object() with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE): HOTP(secret, 8, hashes.SHA1(), pretend_backend)
def __init__(self, key, length, algorithm, time_step, backend): if not isinstance(backend, HMACBackend): raise UnsupportedAlgorithm( "Backend object does not implement HMACBackend.", _Reasons.BACKEND_MISSING_INTERFACE) self._time_step = time_step self._hotp = HOTP(key, length, algorithm, backend)
def test_truncate(self, backend, params): secret = params["secret"] counter = int(params["counter"]) truncated = params["truncated"] hotp = HOTP(secret, 6, SHA1(), backend) assert hotp._dynamic_truncate(counter) == int(truncated.decode(), 16)
def test_generate(self, backend, params): secret = params["secret"] counter = int(params["counter"]) hotp_value = params["hotp"] hotp = HOTP(secret, 6, SHA1(), backend) assert hotp.generate(counter) == hotp_value
def test_invalid_verify(self, backend): secret = b"12345678901234567890" counter = 0 hotp = HOTP(secret, 6, SHA1(), backend) with pytest.raises(InvalidToken): hotp.verify(b"123456", counter)
def __init__( self, key: bytes, length: int, algorithm: _ALLOWED_HASH_TYPES, time_step: int, backend: typing.Any = None, enforce_key_length: bool = True, ): self._time_step = time_step self._hotp = HOTP(key, length, algorithm, enforce_key_length=enforce_key_length)
def test_get_provisioning_uri(self, backend): secret = b"12345678901234567890" hotp = HOTP(secret, 6, SHA1(), backend) assert hotp.get_provisioning_uri( "Alice Smith", 1, None) == ("otpauth://hotp/Alice%20Smith?digits=6&secret=GEZDGNBV" "GY3TQOJQGEZDGNBVGY3TQOJQ&algorithm=SHA1&counter=1") assert hotp.get_provisioning_uri( "Alice Smith", 1, "Foo") == ("otpauth://hotp/Foo:Alice%20Smith?digits=6&secret=GEZD" "GNBVGY3TQOJQGEZDGNBVGY3TQOJQ&algorithm=SHA1&issuer=Foo" "&counter=1")
def generate_hotp_uri(secret, counter, email): """ Generate a Google authenticator compatible QR code provisioning URI Args: secret: 16 character base32 secret counter: unique integer value email: Authenticator email address Return: URI: otpauth://hotp/[email protected]?secret=JBSWY3DPEHPK3PXP&counter=0&issuer=FrostyWeb """ if isinstance(secret, unicode): secret = secret.encode('utf-8') try: key = base64.b32decode(secret) hotp = HOTP(key, 6, SHA1(), backend=default_backend(), enforce_key_length=False) return hotp.get_provisioning_uri(email, counter, 'FrostyWeb') except (ValueError, TypeError): pass return None
def __init__( self, key: bytes, length: int, algorithm: _ALLOWED_HASH_TYPES, time_step: int, backend=None, enforce_key_length: bool = True, ): backend = _get_backend(backend) if not isinstance(backend, HMACBackend): raise UnsupportedAlgorithm( "Backend object does not implement HMACBackend.", _Reasons.BACKEND_MISSING_INTERFACE, ) self._time_step = time_step self._hotp = HOTP(key, length, algorithm, backend, enforce_key_length)
def generate_hotp_code(secret, counter): """ Generate a Google authenticator compatible HOTP code Args: secret: 16 character base32 secret (80 bit key) counter: unique integer value Return: code: 6 digit one time use code """ if isinstance(secret, unicode): secret = secret.encode('utf-8') try: key = base64.b32decode(secret) hotp = HOTP(key, 6, SHA1(), backend=default_backend(), enforce_key_length=False) hotp_value = hotp.generate(counter) return hotp_value except (ValueError, TypeError): pass return None
def primitive(): # Initialize the errors variable to empty string. We will have the error messages # in that variable, if any. errors = '' if request.method == "GET": # If the request is GET, render the form template. return render_template("index.html", errors=errors) if 'aesForm' in request.form: # The request is POST with some data, get POST data and validate it. # The form data is available in request.form dictionary. Stripping it to remove # leading and trailing whitespaces aesPlainText = request.form['aesPlainText'].strip() # Check if all the fields are non-empty and raise an error otherwise if not aesPlainText: errors = "Please enter all the fields." if not errors: # If there are no errors, create a dictionary containing all the entered # data and pass it to the template to be displayed a1 = "Symmetric Encryption\n" a2 = "This application will use DES Symmetric Encryption to encrypt and decrypt text\n" plainText = "Text to encrypt: " getInput = aesPlainText backend = default_backend() cfb_Key = os.urandom(16) aes_Key = os.urandom(32) #secretMessage = str.encode(input(plainText)) secretMessage = str.encode(getInput) cipher = Cipher(algorithms.AES(aes_Key), modes.CFB(cfb_Key), backend=backend) encryptor = cipher.encryptor() encryptedText = encryptor.update( secretMessage) + encryptor.finalize() decryptor = cipher.decryptor() decryptedText = decryptor.update( encryptedText) + decryptor.finalize() dataAes = { 'aes_Key': aes_Key, 'cfb_Key': cfb_Key, 'encryptedText': encryptedText, 'decryptedText': decryptedText } # Since the form data is valid, render the success template return render_template("prim/aes.html", dataAes=dataAes) # Render the form template with the error messages return render_template("index.html", errors=errors) if 'desForm' in request.form: # The request is POST with some data, get POST data and validate it. # The form data is available in request.form dictionary. Stripping it to remove desPlainText = request.form['desPlainText'].strip() #desBitKey = request.form['desBitKey'].strip() #desMode = request.form['desMode'].strip() # Check if all the fields are non-empty and raise an error otherwise if not desPlainText: errors = "Please enter all the fields." if not errors: # If there are no errors, create a dictionary containing all the entered # data and pass it to the template to be displayed plaintext = desPlainText mode = "CBC" key = "12345678" #key and plain text desKey = des(key, mode, "\0\0\0\0\0\0\0\0") #print ("Key : %r" % k.getKey()) #print ("Plaintext : %r" % plaintext) #desKey = k # Encrypted message desEnc = desKey.encrypt(plaintext, [], PAD_PKCS5) #print ("Encrypted: %r" % d) desEncMessage = desEnc # Decrypted message desDec = desKey.decrypt(desEncMessage, [], PAD_PKCS5) #print ("Decrypted Plaintext: %r" % d) desDecMessage = desDec dataDes = { 'desPlainText': desPlainText, 'desKey': desKey, 'desEncMessage': desEncMessage, 'desDecMessage': desDecMessage } # Since the form data is valid, render the success template return render_template("prim/des.html", dataDes=dataDes) # Render the form template with the error messages return render_template("index.html", errors=errors) if 'hmacForm' in request.form: # The request is POST with some data, get POST data and validate it. # The form data is available in request.form dictionary. Stripping it to remove hmacPlainText = request.form['hmacPlainText'].strip() # Check if all the fields are non-empty and raise an error otherwise if not hmacPlainText: errors = "Please enter all the fields." if not errors: # If there are no errors, create a dictionary containing all the entered # data and pass it to the template to be displayed shared_key = os.urandom(16) # Create a HMAC object digest = hmac.HMAC(shared_key, hashes.SHA256(), backend=default_backend()) # enter the message has input to be hased in bytes plaintext = str.encode(hmacPlainText) digest.update(plaintext) # Finalized and produce the HMAC that will be attached to the message hash_code = digest.finalize() print("message", hmacPlainText) print("hash_code", hash_code) print("random Key:", shared_key) dataHmac = { 'hmacPlainText': hmacPlainText, 'hash_code': hash_code, 'shared_key': shared_key } # Since the form data is valid, render the success template return render_template("prim/hmac.html", dataHmac=dataHmac) # Render the form template with the error messages return render_template("index.html", errors=errors) if 'diffForm' in request.form: # The request is POST with some data, get POST data and validate it. # The form data is available in request.form dictionary. Stripping it to remove diifPlainText = request.form['diifPlainText'].strip() diffPub1 = request.form['diffPub1'].strip() diffPub2 = request.form['diffPub2'].strip() # Check if all the fields are non-empty and raise an error otherwise if not diifPlainText or not diffPub1 or not diffPub2: errors = "Please enter all the fields." if not errors: # If there are no errors, create a dictionary containing all the entered # data and pass it to the template to be displayed Xa = int(diffPub1) Xb = int(diffPub2) diifPlainText = int(diifPlainText) check_num = 0 prK = 2 a = prK #Compute Public Key for first user Ya = (a**Xa) % diifPlainText #Compute Public Key for second user Yb = (a**Xb) % diifPlainText #Compute shared key Ka = (Yb**Xa) % diifPlainText Kb = (Ya**Xb) % diifPlainText #Shared key should be same value for both users print("primitive_root: prK and prQ") print("1 shared key is", Ka) print("2 shared key is", Kb, "\n") print("1 and 2 secret shared key is", Ka, "\n") print("primitive_root", prK) print("a_pupKey", Ya) print("a_sharedKey", Ka) print("b_pupKey", Yb) print("b_sharedKey:", Kb) dataDiff = { 'prime': diifPlainText, 'primitive_root': prK, 'a_pupKey': Ya, 'a_sharedKey': Ka, 'b_pupKey': Yb, 'b_sharedKey': Kb } # Since the form data is valid, render the success template return render_template("prim/diff.html", dataDiff=dataDiff) # Render the form template with the error messages return render_template("index.html", errors=errors) if '2faForm' in request.form: # The request is POST with some data, get POST data and validate it. # The form data is available in request.form dictionary. Stripping it to remove #diifPlainText = request.form['diifPlainText'].strip() # Check if all the fields are non-empty and raise an error otherwise #if not diifPlainText or not diffPub1 or not diffPub2: #errors = "Please enter all the fields." if not errors: # If there are no errors, create a dictionary containing all the entered # data and pass it to the template to be displayed #Key is a secret key which is being randomly generated bytes key2Fa = os.urandom(20) #HOTP is an HMAC one-time password algorithm. #Length parameter is controls the length of the generated password which must be >=6 and <=8; Is using SHA1() hash function to encrypt hotp = HOTP(key2Fa, 6, SHA1(), backend=default_backend()) #Hotp.generate, generates the random 6 digit token hotp_value = hotp.generate(0) hotp.verify(hotp_value, 0) print("hashed_value: ", hotp_value) print("generated key: ", key2Fa) data2Fa = {'hotp_value': hotp_value, 'key2Fa': key2Fa} # Since the form data is valid, render the success template return render_template("prim/2fa.html", data2Fa=data2Fa) # Render the form template with the error messages return render_template("index.html", errors=errors)
import matplotlib.pyplot as plt import numpy as np import seaborn as sns import collections def count_frequency(arr): return collections.Counter(arr) if __name__ == '__main__': hotp_holder = [] key = os.urandom(20) hotp = HOTP(key, 8, SHA1(), backend=default_backend()) for x in range(100000): hotp_value = hotp.generate(x) hotp_str = hotp_value.decode("utf-8") n = 2 for i in range(0, len(hotp_str), n): hotp_holder.append(hotp_str[i:i + n]) # matplotlib histogram plt.hist(hotp_holder, color='blue', edgecolor='black', bins=100) # seaborn histogram sns.distplot(hotp_holder, hist=True, kde=False,
def test_invalid_algorithm(self, backend): secret = os.urandom(16) with pytest.raises(UnsupportedAlgorithm): HOTP(secret, 6, MD5(), backend)
def test_invalid_hotp_length(self, backend): secret = os.urandom(16) with pytest.raises(ValueError): HOTP(secret, 4, SHA1(), backend)
def __init__(self, key, length, algorithm, time_step, backend): self._time_step = time_step self._hotp = HOTP(key, length, algorithm, backend)
def test_buffer_protocol(self, backend): key = bytearray(b"a long key with lots of entropy goes here") hotp = HOTP(key, 6, SHA1(), backend) assert hotp.generate(10) == b"559978"
def test_length_not_int(self, backend): secret = b"12345678901234567890" with pytest.raises(TypeError): HOTP(secret, b"foo", SHA1(), backend)
def test_invalid_algorithm(self, backend): secret = os.urandom(16) with pytest.raises(TypeError): HOTP(secret, 6, MD5(), backend)
def test_unenforced_invalid_kwy_length(self, backend): secret = os.urandom(10) HOTP(secret, 6, SHA1(), backend, enforce_key_length=False)