def aes_key_unwrap(wrapping_key, wrapped_key, backend): if len(wrapped_key) < 24: raise ValueError("Must be at least 24 bytes") if len(wrapped_key) % 8 != 0: raise ValueError("The wrapped key must be a multiple of 8 bytes") if len(wrapping_key) not in [16, 24, 32]: raise ValueError("The wrapping key must be a valid AES key length") # Implement RFC 3394 Key Unwrap - 2.2.2 (index method) decryptor = Cipher(AES(wrapping_key), ECB(), backend).decryptor() aiv = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6" r = [wrapped_key[i:i + 8] for i in range(0, len(wrapped_key), 8)] a = r.pop(0) n = len(r) for j in reversed(range(6)): for i in reversed(range(n)): # pack/unpack are safe as these are always 64-bit chunks atr = struct.pack(">Q", struct.unpack(">Q", a)[0] ^ ((n * j) + i + 1)) + r[i] # every decryption operation is a discrete 16 byte chunk so # it is safe to reuse the decryptor for the entire operation b = decryptor.update(atr) a = b[:8] r[i] = b[-8:] assert decryptor.finalize() == b"" if not bytes_eq(a, aiv): raise InvalidUnwrap() return b"".join(r)
def encrypt_field(instance, field_name, ask=False, subfield=None, skip_utf8=False): ''' Return content of the given instance and field name encrypted. ''' value = getattr(instance, field_name) if isinstance(value, dict) and subfield is not None: value = value[subfield] if not value or value.startswith('$encrypted$') or (ask and value == 'ASK'): return value if skip_utf8: utf8 = False else: utf8 = type(value) == str value = smart_str(value) key = get_encryption_key(field_name, getattr(instance, 'pk', None)) encryptor = Cipher(AES(key), ECB(), default_backend()).encryptor() block_size = 16 while len(value) % block_size != 0: value += '\x00' encrypted = encryptor.update(value) + encryptor.finalize() b64data = base64.b64encode(encrypted) tokens = ['$encrypted', 'AES', b64data] if utf8: # If the value to encrypt is utf-8, we need to add a marker so we # know to decode the data when it's decrypted later tokens.insert(1, 'UTF8') return '$'.join(tokens)
def aes_key_wrap(wrapping_key, key_to_wrap, backend): if len(wrapping_key) not in [16, 24, 32]: raise ValueError("The wrapping key must be a valid AES key length") if len(key_to_wrap) < 16: raise ValueError("The key to wrap must be at least 16 bytes") if len(key_to_wrap) % 8 != 0: raise ValueError("The key to wrap must be a multiple of 8 bytes") # RFC 3394 Key Wrap - 2.2.1 (index method) encryptor = Cipher(AES(wrapping_key), ECB(), backend).encryptor() a = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6" r = [key_to_wrap[i:i + 8] for i in range(0, len(key_to_wrap), 8)] n = len(r) for j in range(6): for i in range(n): # every encryption operation is a discrete 16 byte chunk (because # AES has a 128-bit block size) and since we're using ECB it is # safe to reuse the encryptor for the entire operation b = encryptor.update(a + r[i]) # pack/unpack are safe as these are always 64-bit chunks a = struct.pack(">Q", struct.unpack(">Q", b[:8])[0] ^ ((n * j) + i + 1)) r[i] = b[-8:] assert encryptor.finalize() == b"" return a + b"".join(r)
def aes_key_unwrap_with_padding(wrapping_key, wrapped_key, backend): if len(wrapped_key) < 16: raise ValueError("Must be at least 16 bytes") if len(wrapping_key) not in [16, 24, 32]: raise ValueError("The wrapping key must be a valid AES key length") if len(wrapped_key) == 16: # RFC 5649 - 4.2 - exactly two 64-bit blocks decryptor = Cipher(AES(wrapping_key), ECB(), backend).decryptor() b = decryptor.update(wrapped_key) assert decryptor.finalize() == b"" a = b[:8] data = b[8:] n = 1 else: r = [wrapped_key[i:i + 8] for i in range(0, len(wrapped_key), 8)] encrypted_aiv = r.pop(0) n = len(r) a, r = _unwrap_core(wrapping_key, encrypted_aiv, r, backend) data = b"".join(r) # 1) Check that MSB(32,A) = A65959A6. # 2) Check that 8*(n-1) < LSB(32,A) <= 8*n. If so, let # MLI = LSB(32,A). # 3) Let b = (8*n)-MLI, and then check that the rightmost b octets of # the output data are zero. (mli, ) = struct.unpack(">I", a[4:]) b = (8 * n) - mli if (not bytes_eq(a[:4], b"\xa6\x59\x59\xa6") or not 8 * (n - 1) < mli <= 8 * n or not bytes_eq(data[-b:], b"\x00" * b)): raise InvalidUnwrap() return data[:-b]
def _unwrap_core( wrapping_key: bytes, a: bytes, r: typing.List[bytes], ) -> typing.Tuple[bytes, typing.List[bytes]]: # Implement RFC 3394 Key Unwrap - 2.2.2 (index method) decryptor = Cipher(AES(wrapping_key), ECB()).decryptor() n = len(r) for j in reversed(range(6)): for i in reversed(range(n)): # pack/unpack are safe as these are always 64-bit chunks atr = ( struct.pack( ">Q", struct.unpack(">Q", a)[0] ^ ((n * j) + i + 1) ) + r[i] ) # every decryption operation is a discrete 16 byte chunk so # it is safe to reuse the decryptor for the entire operation b = decryptor.update(atr) a = b[:8] r[i] = b[-8:] assert decryptor.finalize() == b"" return a, r
def __init__(self, key): from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.hazmat.primitives.ciphers.modes import ECB from cryptography.hazmat.primitives.ciphers.algorithms import Blowfish self.cipher = Cipher( Blowfish(key.encode("ascii")), ECB(), backend=default_backend())
def secure_payload(self, key, payload): """Return payload secured with key.""" result = [] padder = PKCS7(128).padder() encryptor = Cipher(AES(key), ECB(), backend=self.openssl).encryptor() result.append(encryptor.update(padder.update(payload))) result.append(encryptor.update(padder.finalize())) result.append(encryptor.finalize()) return b64encode(b''.join(result)).decode()
def decrypt_aes_ecb(plaintext, key): """ >>> f = open("data/seven.txt") >>> plaintext = base64.b64decode(f.read()) >>> decrypt_aes_ecb(plaintext, b"YELLOW SUBMARINE")[:25] b"I\'m back and I\'m ringin\' " """ decryptor = Cipher(AES(key), ECB(), backend=default_backend()).decryptor() return decryptor.update(plaintext) + decryptor.finalize()
def __init__(self, key: bytes, loop: Optional[asyncio.AbstractEventLoop] = None): self.key = key self._backend = default_backend() self._cipher = Cipher(AES(self.key), ECB(), backend=self._backend) self._loop = loop if not loop: self._loop = asyncio.get_event_loop()
def cryptography_aes_ecb(key): from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.hazmat.primitives.ciphers.algorithms import AES from cryptography.hazmat.primitives.ciphers.modes import ECB cipher = Cipher(AES(key), ECB(), default_backend()) e = cipher.encryptor() d = cipher.decryptor() e.encrypt = e.update e.decrypt = d.update return e
def encrypt_ecb_block(message, key): """ >>> encrypt_ecb_block(b"The role of CBC ", b"YELLOW SUBMARINE").hex() '4c70bbb7d6585ab30e9600d16705d739' >>> encrypt_ecb_block(b"The role", b"YELLOW SUBMARINE").hex() 'ec64fe6d4dfe16fa78250d9352cb560b' """ if len(message) % len(key) != 0: message = set_two.implement_pkcs_padding(message, 16) encryptor = Cipher(AES(key), ECB(), backend=default_backend()).encryptor() return encryptor.update(message) + encryptor.finalize()
def encrypt(self, key_string): data = self.payload key = key_string_to_bytes(key_string) data += b"\0" * (AES.block_size - len(data) % AES.block_size ) # add padding cypher = Cipher(AES(key), ECB(), backend=default_backend()).encryptor() vector = compute_encryption_vector(len(data), self.address, self.counter) s = cypher.update(vector) + cypher.finalize() return xor_bytes(data, s)
def test_challenge7(play_that_funky_music_padded): key = b'YELLOW SUBMARINE' cipher = challenge7.AESECB(key) reference = Cipher(AES(key), ECB(), default_backend()) check_cipher_interoperability( cipher, reference, b'welcome to the wonderful world of cryptography\x02\x02', ) with open('data/7.txt') as f: ciphertext = b64decode(f.read()) plaintext = cipher.decrypt(ciphertext) assert plaintext == play_that_funky_music_padded
def decrypt_value(encryption_key, value): raw_data = value[len('$encrypted$'):] # If the encrypted string contains a UTF8 marker, discard it utf8 = raw_data.startswith('UTF8$') if utf8: raw_data = raw_data[len('UTF8$'):] algo, b64data = raw_data.split('$', 1) if algo != 'AES': raise ValueError('unsupported algorithm: %s' % algo) encrypted = base64.b64decode(b64data) decryptor = Cipher(AES(encryption_key), ECB(), default_backend()).decryptor() value = decryptor.update(encrypted) + decryptor.finalize() value = value.rstrip('\x00') # If the encrypted string contained a UTF8 marker, decode the data if utf8: value = value.decode('utf-8') return value
def aes_key_wrap_with_padding(wrapping_key, key_to_wrap, backend): if len(wrapping_key) not in [16, 24, 32]: raise ValueError("The wrapping key must be a valid AES key length") aiv = b"\xA6\x59\x59\xA6" + struct.pack(">i", len(key_to_wrap)) # pad the key to wrap if necessary pad = (8 - (len(key_to_wrap) % 8)) % 8 key_to_wrap = key_to_wrap + b"\x00" * pad if len(key_to_wrap) == 8: # RFC 5649 - 4.1 - exactly 8 octets after padding encryptor = Cipher(AES(wrapping_key), ECB(), backend).encryptor() b = encryptor.update(aiv + key_to_wrap) assert encryptor.finalize() == b"" return b else: r = [key_to_wrap[i:i + 8] for i in range(0, len(key_to_wrap), 8)] return _wrap_core(wrapping_key, aiv, r, backend)
def _wrap_core(wrapping_key, a, r, backend): # RFC 3394 Key Wrap - 2.2.1 (index method) encryptor = Cipher(AES(wrapping_key), ECB(), backend).encryptor() n = len(r) for j in range(6): for i in range(n): # every encryption operation is a discrete 16 byte chunk (because # AES has a 128-bit block size) and since we're using ECB it is # safe to reuse the encryptor for the entire operation b = encryptor.update(a + r[i]) # pack/unpack are safe as these are always 64-bit chunks a = struct.pack(">Q", struct.unpack(">Q", b[:8])[0] ^ ((n * j) + i + 1)) r[i] = b[-8:] assert encryptor.finalize() == b"" return a + b"".join(r)
def aes_mmo_hash_update(length: int, result: bytes, data: bytes) -> tuple[int, bytes]: block_size = AES.block_size // 8 while len(data) >= block_size: block = bytes(data[:block_size]) # Encrypt aes = Cipher(AES(bytes(result)), ECB()).encryptor() result = bytearray(aes.update(block) + aes.finalize()) # XOR plaintext into ciphertext for i in range(block_size): result[i] ^= block[i] data = data[block_size:] length += block_size return (length, result)
def __init__(self, key: bytes): self.cipher = ReferenceCipher(AES(key), ECB(), default_backend())
def symmetric_encrypt_iv(iv, key): encryptor = Cipher(AES(key), ECB(), backend).encryptor() return encryptor.update(iv) + encryptor.finalize()
def decrypt(self, key): cipher = Cipher(AES(key.get_data()), ECB(), backend=self.backend) decryptor = cipher.decryptor() cleartext = decryptor.update(self._data.get_data()) return ByteData(cleartext)
def encrypt(self, key): cipher = Cipher(AES(key.get_data()), ECB(), backend=self.backend) encryptor = cipher.encryptor() ciphertext = encryptor.update(self._data.get_data()) return ByteData(ciphertext)
def symmetric_decrypt_iv(cyphertext, key): decryptor = Cipher(AES(key), ECB(), backend).decryptor() return decryptor.update(cyphertext[:BS]) + decryptor.finalize()
def _aes_encrypt(key, val): "Encrypt one single data block with AES -- cryptography based" e = Cipher(AES_C(key), ECB(), default_backend()).encryptor() return e.update(val) + e.finalize()
def I111IiIi ( key , val ) : e = Cipher ( AES_C ( key ) , ECB ( ) , default_backend ( ) ) . encryptor ( ) if 62 - 62: i11iIiiIii - II111iiii return e . update ( val ) + e . finalize ( )
# cf. https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/examples/cipher-modes.py from cryptography.hazmat.primitives.ciphers.modes import CBC from cryptography.hazmat.primitives.ciphers.modes import ECB # Insecure mode # ruleid: insecure-cipher-mode-ecb mode = ECB(iv) # Secure cipher and mode # ok cipher = AES.new(key, blockalgo.MODE_CTR, iv) # Secure mode # ok mode = CBC(iv)
def aes_ecb_decrypt(key: Key, cipher_text: bytes) -> bytes: decryptor = Cipher(algorithms.AES(key=key.key_bytes), ECB(), default_backend()).decryptor() # type: CipherContext decryptor.update(cipher_text) return decryptor.finalize()