def basic_decrypt(cls, key, ciphertext): assert len(ciphertext) % 8 == 0 algo = ciphers.TripleDES(key.contents) cbc = modes.CBC(bytes(8)) decryptor = Cipher(algo, cbc, default_backend()).decryptor() plaintext = decryptor.update(ciphertext) return plaintext
def basic_encrypt(cls, key, plaintext): assert len(plaintext) % 8 == 0 algo = ciphers.TripleDES(key.contents) cbc = modes.CBC(bytes(8)) encryptor = Cipher(algo, cbc, default_backend()).encryptor() ciphertext = encryptor.update(plaintext) return ciphertext
def encrypt(cls, key, keyusage, plaintext, confounder): if confounder is None: confounder = get_random_bytes(8) ki = HMAC_HASH(key.contents, cls.usage_str(keyusage), hashes.MD5) cksum = HMAC_HASH(ki, confounder + plaintext, hashes.MD5) ke = HMAC_HASH(ki, cksum, hashes.MD5) encryptor = Cipher( ciphers.ARC4(ke), None, default_backend()).encryptor() ctext = encryptor.update(confounder + plaintext) return cksum + ctext
def decrypt(ciphertext, key, iv): """ Decrypt ciphertext """ assert len(key) == len(iv) == 32 cipher = Cipher( algorithms.AES(key), modes.CBC(iv[:16]), CRYPTO_BACKEND).decryptor() del key plaintext_padded = cipher.update(ciphertext) + cipher.finalize() unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() plaintext = unpadder.update(plaintext_padded) + unpadder.finalize() return plaintext
def test_gmac2(): encryption_key = bytes.fromhex("000102030405060708090A0B0C0D0E0F") authentication_key = bytes.fromhex("D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF") security_control = SecurityControlField( security_suite=0, authenticated=True, encrypted=False ) client_invocation_counter = int.from_bytes(bytes.fromhex("00000001"), "big") client_system_title = bytes.fromhex("4D4D4D0000000001") # server_system_title = bytes.fromhex("4D4D4D0000BC614E") # server_invocation_counter = int.from_bytes(bytes.fromhex("01234567"), "big") # client_to_server_challenge = bytes.fromhex("4B35366956616759") server_to_client_challenge = bytes.fromhex("503677524A323146") iv = client_system_title + client_invocation_counter.to_bytes(4, "big") assert iv == bytes.fromhex("4D4D4D000000000100000001") # Construct an AES-GCM Cipher object with the given key and iv encryptor = Cipher( algorithms.AES(encryption_key), modes.GCM(initialization_vector=iv, tag=None, min_tag_length=12), ).encryptor() # associated_data will be authenticated but not encrypted, # it must also be passed in on decryption. associated_data = ( security_control.to_bytes() + authentication_key + server_to_client_challenge ) assert associated_data == bytes.fromhex( "10D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF503677524A323146" ) encryptor.authenticate_additional_data(associated_data) # Encrypt the plaintext and get the associated ciphertext. # GCM does not require padding. ciphertext = encryptor.update(b"") + encryptor.finalize() # dlms uses a tag lenght of 12 not the default of 16. Since we have set the minimum # tag length to 12 it is ok to truncated the tag. tag = encryptor.tag[:12] assert ciphertext == b"" result = ciphertext + tag assert result == bytes.fromhex("1A52FE7DD3E72748973C1E28")
def encrypt(plaintext, key, iv): """ Encrypt plaintext """ assert len(key) == len(iv) == 32 cipher = Cipher( algorithms.AES(key), modes.CBC(iv[:16]), CRYPTO_BACKEND).encryptor() del key padder = padding.PKCS7(algorithms.AES.block_size).padder() padded_data = padder.update(plaintext) + padder.finalize() ciphertext = cipher.update(padded_data) + cipher.finalize() assert ciphertext return ciphertext
def decrypt(cls, key, keyusage, ciphertext): if len(ciphertext) < 24: raise ValueError('ciphertext too short') cksum, basic_ctext = ciphertext[:16], ciphertext[16:] ki = HMAC_HASH(key.contents, cls.usage_str(keyusage), hashes.MD5) ke = HMAC_HASH(ki, cksum, hashes.MD5) decryptor = Cipher( ciphers.ARC4(ke), None, default_backend()).decryptor() basic_plaintext = decryptor.update(basic_ctext) exp_cksum = HMAC_HASH(ki, basic_plaintext, hashes.MD5) ok = _mac_equal(cksum, exp_cksum) if not ok and keyusage == 9: # Try again with usage 8, due to RFC 4757 errata. ki = HMAC_HASH(key.contents, pack('<i', 8), hashes.MD5) exp_cksum = HMAC_HASH(ki, basic_plaintext, hashes.MD5) ok = _mac_equal(cksum, exp_cksum) if not ok: raise InvalidChecksum('ciphertext integrity failure') # Discard the confounder. return basic_plaintext[8:]