def test_aes_gcm(backend, wycheproof): key = binascii.unhexlify(wycheproof.testcase["key"]) iv = binascii.unhexlify(wycheproof.testcase["iv"]) aad = binascii.unhexlify(wycheproof.testcase["aad"]) msg = binascii.unhexlify(wycheproof.testcase["msg"]) ct = binascii.unhexlify(wycheproof.testcase["ct"]) tag = binascii.unhexlify(wycheproof.testcase["tag"]) if wycheproof.valid or wycheproof.acceptable: enc = Cipher(algorithms.AES(key), modes.GCM(iv), backend).encryptor() enc.authenticate_additional_data(aad) computed_ct = enc.update(msg) + enc.finalize() computed_tag = enc.tag assert computed_ct == ct assert computed_tag == tag dec = Cipher( algorithms.AES(key), modes.GCM(iv, tag, min_tag_length=len(tag)), backend ).decryptor() dec.authenticate_additional_data(aad) computed_msg = dec.update(ct) + dec.finalize() assert computed_msg == msg elif len(iv) == 0: with pytest.raises(ValueError): Cipher(algorithms.AES(key), modes.GCM(iv), backend) else: dec = Cipher( algorithms.AES(key), modes.GCM(iv, tag, min_tag_length=len(tag)), backend ).decryptor() dec.authenticate_additional_data(aad) dec.update(ct) with pytest.raises(InvalidTag): dec.finalize()
def decrypt(self): pad = self.enc_pad(self.enckey, self.pad_iv) aes = Cipher(AES(self.enckey), CTR(self.iv), default_backend()).decryptor() self.fwd = pad + aes.update(self.onion[:self.fwd_end]) self.msg = aes.update(self.onion[self.fwd_end:self.msg_end])
class Rc4Xform(s_socket.SockXform): def __init__(self, rc4key): self.rc4key = rc4key def init(self, sock): txnonce = os.urandom(16) try: sock.setblocking(1) sock._raw_sendall(txnonce) rxnonce = sock._raw_recvall(16) if rxnonce == None: return txkey = hashlib.sha256( txnonce + self.rc4key ).digest() rxkey = hashlib.sha256( rxnonce + self.rc4key ).digest() self.txcrypt = Cipher( ARC4(txkey), mode=None, backend=default_backend() ).encryptor() self.rxcrypt = Cipher( ARC4(rxkey), mode=None, backend=default_backend() ).decryptor() finally: if sock.plex: sock.setblocking(0) def txform(self, byts): return self.txcrypt.update(byts) def rxform(self, byts): return self.rxcrypt.update(byts)
def main(): if type(cipher_key) != str or len(cipher_key) != cipher_key_bytelen: return "no key", 500 auth = request.args.get('auth', None) if auth is None: cleartext = '{"userid":%d,"is_admin":0}' % random.randint(1000000, 2000000) iv = os.urandom(cipher_block_bytelen) padder = padding.PKCS7(cipher.block_size).padder() padded_data = padder.update(cleartext) + padder.finalize() encryptor = Cipher(cipher(cipher_key), modes.CBC(iv), backend=backend).encryptor() ciphertext = encryptor.update(padded_data) + encryptor.finalize() return redirect('/?auth=' + binascii.hexlify(iv + ciphertext)) try: received = binascii.unhexlify(auth) except: return "hex error", 400 # print "received" # hexdump.hexdump(received) # sys.stdout.flush() if len(received) < cipher_block_bytelen * 2: return "input too short", 400 iv, ciphertext = received[:cipher_block_bytelen], received[cipher_block_bytelen:] decryptor = Cipher(cipher(cipher_key), modes.CBC(iv), backend=backend).decryptor() decrypted = decryptor.update(ciphertext) + decryptor.finalize() # print "decrypted" # hexdump.hexdump(decrypted) # sys.stdout.flush() unpadder = padding.PKCS7(cipher.block_size).unpadder() unpadded = unpadder.update(decrypted) try: unpadded += unpadder.finalize() except ValueError: return "padding error", 400 # print "unpadded" # hexdump.hexdump(unpadded) # sys.stdout.flush() try: decoded = unpadded.decode('utf-8') parsed = json.loads(decoded) except: return "parsing error", 400 if type(parsed) != dict or 'userid' not in parsed or 'is_admin' not in parsed: return "parsing error", 400 if parsed['is_admin']: return "Hello user #%d, you are admin!" % parsed['userid'] else: return "Hello user #%d!" % parsed['userid']
class Rc4Skey(s_socket.SockXform): def __init__(self, rc4key): self.rc4key = rc4key self.txcrypt = Cipher( ARC4(rc4key), mode=None, backend=default_backend() ).encryptor() self.rxcrypt = Cipher( ARC4(rc4key), mode=None, backend=default_backend() ).decryptor() def init(self, sock): pass def txform(self, byts): return self.txcrypt.update(byts) def rxform(self, byts): return self.rxcrypt.update(byts)
def encrypt_with_hmac(self, data, data_id, iv): if not isinstance(data, bytes): raise TypeError("data must be bytes.") if not isinstance(data_id, int): raise TypeError("data_id must be int.") main_parts = ( struct.pack(config.FORMAT_CHAR, data_id) + data ) # PKCS7 padding padded_data = self.add_padding(main_parts, algorithms.AES.block_size) # AES with CBC mode encryptor = Cipher(algorithms.AES(self.aes_key), modes.CBC(iv), backend=self.backend).encryptor() ciphertext = encryptor.update(padded_data) + encryptor.finalize() basic_parts = ( b"\x80" + iv + ciphertext ) h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend) h.update(basic_parts) hmac = h.finalize() return basic_parts + hmac
def encrypt_v3(a_key, a_token, a_verbose = False): # Get sha-256 of key l_key = hashlib.sha256(a_key).hexdigest().decode('hex') # Generate iv l_iv = os.urandom(G_IV_SIZE_BYTES) # TODO Make constant... # Construct an AES-GCM Cipher object with the given key and a # randomly generated IV. l_encryptor = Cipher( algorithms.AES(l_key), modes.GCM(l_iv), backend=default_backend() ).encryptor() # Encrypt the plaintext and get the associated ciphertext. # GCM does not require padding. l_ciphertext = l_encryptor.update(a_token) + l_encryptor.finalize() l_iv_ciphertext = l_iv + l_ciphertext + l_encryptor.tag #print 'TAG (len:%d) : %s'%(len(l_encryptor.tag), l_encryptor.tag) if a_verbose: print('+-------------------------------------------------------------') print('| l_iv: %s'%(l_iv.encode('hex'))) print('| l_ciphertext: %s'%(l_ciphertext.encode('hex'))) print('| l_tag: %s'%(l_encryptor.tag.encode('hex'))) print('+-------------------------------------------------------------') print('| l_encoded_token: %s'%(l_iv_ciphertext.encode('hex'))) print('+-------------------------------------------------------------') return url_safe_base64_encode(l_iv_ciphertext)
def decrypt_file(cipher_text): iv = cipher_text[:IV_LEN] decryptor = Cipher( algorithms.AES(key), modes.GCM(iv, cipher_text[IV_LEN:IV_LEN+TAG_LEN]), backend=b.default_backend()).decryptor() return decryptor.update(cipher_text[IV_LEN+TAG_LEN:]) + decryptor.finalize()
def encrypt(encryption_key, iv, data): """Encrypt the payload.""" padder = padding.PKCS7(algorithms.AES.block_size).padder() data = padder.update(data.encode()) + padder.finalize() encryptor = Cipher(algorithms.AES(encryption_key), modes.CBC(iv), default_backend()).encryptor() return base64.urlsafe_b64encode(encryptor.update(data) + encryptor.finalize())
def generate_secure_text(self, origin_text: str) -> str: """ Encrypt and sign the origin text by ``cryptography`` library using AES GCM algorithm. :arg origin_text: is a string that will be encrypted by the provided security secret. """ iv = os.urandom(16) content = struct.pack( "l", int(time.time())) + ensure_bytes(origin_text) encryptor = AESCipher( aes_algorithms.AES(ensure_bytes(self.__security_secret)), aes_modes.GCM(iv), backend=aes_backend() ).encryptor() ciphertext = encryptor.update(content) + encryptor.finalize() final_encrypted_text = iv final_encrypted_text += struct.pack("l", len(ciphertext)) final_encrypted_text += ciphertext final_encrypted_text += encryptor.tag return ensure_str(base64.b64encode(final_encrypted_text))
def unwrap(self, key, ek): rk = self.get_key(key, 'decrypt') # Implement RFC 3394 Key Unwrap - 2.2.3 # TODO: Use cryptography once issue #1733 is resolved iv = 'a6a6a6a6a6a6a6a6' Aiv = unhexlify(iv) R = [ek[i:i+8] for i in range(0, len(ek), 8)] A = R.pop(0) n = len(R) for j in range(5, -1, -1): for i in range(n - 1, -1, -1): AtR = _encode_int((_decode_int(A) ^ ((n*j)+i+1)), 64) + R[i] d = Cipher(algorithms.AES(rk), modes.ECB(), backend=self.backend).decryptor() B = d.update(AtR) + d.finalize() A = B[:8] R[i] = B[-8:] if A != Aiv: raise InvalidJWEData('Decryption Failed') cek = b''.join(R) return cek
def _decrypt_data(self, data, timestamp, ttl): current_time = int(time.time()) if ttl is not None: if timestamp + ttl < current_time: raise InvalidToken if current_time + _MAX_CLOCK_SKEW < timestamp: raise InvalidToken h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend) h.update(data[:-32]) try: h.verify(data[-32:]) except InvalidSignature: raise InvalidToken iv = data[9:25] ciphertext = data[25:-32] decryptor = Cipher( algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend ).decryptor() plaintext_padded = decryptor.update(ciphertext) try: plaintext_padded += decryptor.finalize() except ValueError: raise InvalidToken unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() unpadded = unpadder.update(plaintext_padded) try: unpadded += unpadder.finalize() except ValueError: raise InvalidToken return unpadded
def decrypt(value, key, stash=None): """ Return a decrypted value """ # extract fields using a regex res = re.match(r'^ENC\[AES256_GCM,data:(.+),iv:(.+),aad:(.+),tag:(.+)\]$', value) # if the value isn't in encrypted form, return it as is if res is None: return value enc_value = b64decode(res.group(1)) iv = b64decode(res.group(2)) aad = b64decode(res.group(3)) tag = b64decode(res.group(4)) decryptor = Cipher(algorithms.AES(key), modes.GCM(iv, tag), default_backend() ).decryptor() decryptor.authenticate_additional_data(aad) cleartext = decryptor.update(enc_value) + decryptor.finalize() if stash: # save the values for later if we need to reencrypt stash['iv'] = iv stash['aad'] = aad stash['cleartext'] = cleartext return cleartext
def decrypt(data, key): iv = data[0:16] data = data[16:] cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()).decryptor() data = cipher.update(data) + cipher.finalize() padder = padding.PKCS7(128).unpadder() return padder.update(data) + padder.finalize()
def encrypt(self, orig_pkt, assoclen=None): """encrypt a MACsec frame for this Secure Association""" hdr = copy.deepcopy(orig_pkt) del hdr[MACsec].payload del hdr[MACsec].type pktlen = len(orig_pkt) if self.send_sci: hdrlen = NOSCI_LEN + SCI_LEN else: hdrlen = NOSCI_LEN if assoclen is None or not self.do_encrypt: if self.do_encrypt: assoclen = hdrlen else: assoclen = pktlen iv = self.make_iv(orig_pkt) assoc, pt, _ = MACsecSA.split_pkt(orig_pkt, assoclen) encryptor = Cipher( algorithms.AES(self.key), modes.GCM(iv), backend=default_backend() ).encryptor() encryptor.authenticate_additional_data(assoc) ct = encryptor.update(pt) + encryptor.finalize() hdr[MACsec].payload = Raw(assoc[hdrlen:assoclen] + ct + encryptor.tag) return hdr
def aes_decrypt(passphrase, data): data = data.split('\n') if len(data) < 3: raise ValueError('Invalid encryption data') enc_salt = base64.b64decode(data[0]) enc_iv = base64.b64decode(data[1]) enc_data = base64.b64decode(data[2]) kdf = PBKDF2HMAC( algorithm=hashes.SHA1(), length=32, salt=enc_salt, iterations=1000, backend=default_backend(), ) enc_key = kdf.derive(passphrase) cipher = Cipher( algorithms.AES(enc_key), modes.CBC(enc_iv), backend=default_backend() ).decryptor() data = cipher.update(enc_data) + cipher.finalize() return data.replace('\x00', '')
def decrypt(key, associated_data, iv, ciphertext, tag): # Construct a Cipher object, with the key, iv, and additionally the # GCM tag used for authenticating the message. # OK.. all the objects passed in to this function are of type bytearray, but, it turns # out that the Cipher suite needs strings, despite saying in the documentation that it needs # bytes. Consequently all the parameter objects had to be converted to strings, hence the str() # around each one. # The moral of this story is strong typing is good. try: decryptor = Cipher( algorithms.AES(str(key)), modes.GCM(str(iv), str(tag)), backend=default_backend() ).decryptor() # We put associated_data back in or the tag will fail to verify # when we finalize the decryptor. decryptor.authenticate_additional_data(str(associated_data)) # Decryption gets us the authenticated plaintext. # If the tag does not match an InvalidTag exception will be raised. ret = decryptor.update(str(ciphertext)) + decryptor.finalize() except Exception as e: print(" Failed to de-crypt Measurement with exception: {}: {}".format(e.__class__.__name__, e)) ret = None return ret
def decrypt(self, orig_pkt, assoclen=None): """decrypt a MACsec frame for this Secure Association""" hdr = copy.deepcopy(orig_pkt) del hdr[MACsec].payload pktlen = len(orig_pkt) if self.send_sci: hdrlen = NOSCI_LEN + SCI_LEN else: hdrlen = NOSCI_LEN if assoclen is None or not self.do_encrypt: if self.do_encrypt: assoclen = hdrlen else: assoclen = pktlen - self.icvlen iv = self.make_iv(hdr) assoc, ct, icv = MACsecSA.split_pkt(orig_pkt, assoclen, self.icvlen) decryptor = Cipher( algorithms.AES(self.key), modes.GCM(iv, icv), backend=default_backend() ).decryptor() decryptor.authenticate_additional_data(assoc) pt = assoc[hdrlen:assoclen] pt += decryptor.update(ct) pt += decryptor.finalize() hdr[MACsec].type = struct.unpack('!H', pt[0:2])[0] hdr[MACsec].payload = Raw(pt[2:]) return hdr
def aes_encrypt(passphrase, data): enc_salt = os.urandom(32) enc_iv = os.urandom(16) kdf = PBKDF2HMAC( algorithm=hashes.SHA1(), length=32, salt=enc_salt, iterations=1000, backend=default_backend(), ) enc_key = kdf.derive(passphrase) data += '\x00' * (16 - (len(data) % 16)) cipher = Cipher( algorithms.AES(enc_key), modes.CBC(enc_iv), backend=default_backend() ).encryptor() enc_data = cipher.update(data) + cipher.finalize() return '\n'.join([ base64.b64encode(enc_salt), base64.b64encode(enc_iv), base64.b64encode(enc_data), ])
def lookup_origin_text( self, secure_text: str, valid_length: Optional[int]=None) -> str: try: encrypted_text_reader = io.BytesIO(base64.b64decode(secure_text)) except: # Unable to decode the data. return None try: iv = encrypted_text_reader.read(16) length = struct.unpack("l", encrypted_text_reader.read(8))[0] ciphertext = encrypted_text_reader.read(length) tag = encrypted_text_reader.read(16) except: # Unable to split the data. return None decryptor = AESCipher( aes_algorithms.AES(self._security_secret), aes_modes.GCM(iv, tag), backend=aes_backend() ).decryptor() try: content = decryptor.update(ciphertext) + decryptor.finalize() except: # Unable to decrypt and/or verify the data. return None timestamp = struct.unpack("l", content[:8])[0] text = content[8:] if valid_length and int(time.time()) - timestamp > valid_length: return None # Data Expired. return ensure_str(text)
def decrypt(self, data, ttl=None): """ :type data: bytes :type ttl: int :rtype: bytes """ data = self._signer.unsign(data, ttl) iv = data[:16] ciphertext = data[16:] decryptor = Cipher( algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend).decryptor() plaintext_padded = decryptor.update(ciphertext) try: plaintext_padded += decryptor.finalize() except ValueError: raise InvalidToken # Remove padding unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() unpadded = unpadder.update(plaintext_padded) try: unpadded += unpadder.finalize() except ValueError: raise InvalidToken return unpadded
def unwrap(self, key, keylen, ek, headers): rk = self._get_key(key, 'decrypt') # Implement RFC 3394 Key Unwrap - 2.2.3 # TODO: Use cryptography once issue #1733 is resolved iv = 'a6a6a6a6a6a6a6a6' aiv = unhexlify(iv) r = [ek[i:i + 8] for i in range(0, len(ek), 8)] a = r.pop(0) n = len(r) for j in range(5, -1, -1): for i in range(n - 1, -1, -1): da = _decode_int(a) atr = _encode_int((da ^ ((n * j) + i + 1)), 64) + r[i] d = Cipher(algorithms.AES(rk), modes.ECB(), backend=self.backend).decryptor() b = d.update(atr) + d.finalize() a = b[:8] r[i] = b[-8:] if a != aiv: raise InvalidJWEData('Decryption Failed') cek = b''.join(r) if len(cek) != keylen: raise InvalidJWEKeyLength(keylen, len(cek)) return cek
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(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 verifyThenDecrypt(cipher, emailTime, key): encryptKey = key[16:] signKey = key[:16] payload = base64.urlsafe_b64decode(cipher) #verify timestamp to prevent replay try: timestamp, = struct.unpack(">Q", payload[1:9]) except struct.error: raise ValueError('Invalid message') if timestamp + TTL < emailTime: raise Exception('Invalid timestamp: replay attack detected') #verify HMAC hasher = HMAC(signKey, hashes.SHA256(), backend=default_backend()) hasher.update(payload[:-32]) try: hasher.verify(payload[-32:]) except InvalidSignature: raise Exception('Invalid HMAC: data modification detected') #decrypt cipher text iv = payload[9:25] ciphertext = payload[25:-32] decryptor = Cipher(algorithms.AES(encryptKey), modes.CBC(iv), default_backend()).decryptor() paddedPlaintext = decryptor.update(ciphertext) paddedPlaintext += decryptor.finalize() unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() plaintext = unpadder.update(paddedPlaintext) plaintext += unpadder.finalize() return plaintext
def wrap_key(self, wrapping_key, key_to_wrap): # we don't use an RFC 3394 key wrap algorithm such as cryptography's # aes_wrap_key because it's slower and we have iv material readily # available so don't need a deterministic algorithm iv = self.create_iv() encryptor = Cipher(algorithms.AES(wrapping_key), modes.CTR(iv), backend=self.backend).encryptor() return {"key": encryptor.update(key_to_wrap), "iv": iv}
def encrypt(self, data): """ .. warning:: This should really have thread controls in it. If two threads are simutaneously encrypting, there is a small chance that the IVs would be the same. This would be **extremely** bad. :param data: The data to encrypt :type data: bytes :returns: IV + payload + TAG :rtype: bytes """ # Grab && increment iv iv = self.iv self.iv = (int.from_bytes(iv, 'big') + 1).to_bytes(len(iv), 'big') # TODO: Do we have to make the encryptor every time? # Make the encryptor encryptor = Cipher(algorithms.AES(self.key), modes.GCM(iv), backend=default_backend() ).encryptor() # Encrypt the data encryptor.authenticate_additional_data(iv) ciphertext = encryptor.update(data) + encryptor.finalize() return iv + ciphertext + encryptor.tag
def decrypt(self, data): """ Decrypts an AESGCM payload. Relies on constants: :attr:`~crypto.aesgcm.IV_SIZE` :attr:`~crypto.aesgcm.TAG_SIZE` :param data: The raw data to decrypt :type data: bytes :returns: Decrypted data :rtype: bytes """ iv = data[:IV_SIZE] payload = data[IV_SIZE: -TAG_SIZE] tag = data[-TAG_SIZE:] decryptor = Cipher( algorithms.AES(self.key), modes.GCM(iv, tag), backend=default_backend() ).decryptor() decryptor.authenticate_additional_data(iv) return decryptor.update(payload) + decryptor.finalize()
def _decrypt_aesgcm(key, nonce, ciphertext_tag, associated_data): """ Decrypts a ciphertext with associated data with AES GCM. Args: key: encryption key nonce: nonce for encryption ciphertext_tag: ciphertext with appended tag to decrypt associated_data: additional authenticated associated data (the AD in AEAD) Returns: decrypted plaintext """ if len(ciphertext_tag) < MAC_BYTES: raise NoiseError('Truncated ciphertext (length < authentication tag length).') algo = algorithms.AES(key) assert len(nonce) == 12, 'Expected 96 bit nonce for AES-GCM' ciphertext, tag = ciphertext_tag[:-MAC_BYTES], ciphertext_tag[-MAC_BYTES:] mode = modes.GCM(nonce, tag) decryptor = Cipher(algo, mode, backend).decryptor() decryptor.authenticate_additional_data(associated_data) try: return decryptor.update(ciphertext) + decryptor.finalize() except InvalidTag as invalid_tag: raise NoiseError('GMAC failure') from invalid_tag
def decrypt(packed_encrypted_data, key, mac_key='', backend=BACKEND): """ Decrypts packed encrypted data as returned by encrypt with the same key. If extra data is present, returns plaintext, extra_data. If not, returns plaintext. Raises InvalidTag on authentication failure. """ header, ciphertext, iv, tag, extra_data = load_data(packed_encrypted_data) algorithm, mode, authentication_algorithm = header.split('_', 2) if algorithm.lower() in hashlib.algorithms_guaranteed: return cryptographyless.decrypt(packed_encrypted_data, key, mac_key, backend) mode_args = (iv, tag) if mode in AEAD_MODES else (iv, ) decryptor = Cipher(getattr(algorithms, algorithm)(key), getattr(modes, mode)(*mode_args), backend=BACKEND).decryptor() if mode in AEAD_MODES: decryptor.authenticate_additional_data(extra_data) else: if not mac_key: raise ValueError("mac_key not supplied for {} mode".format(header)) if not verify_mac(mac_key, save_data(tag, header + ciphertext + iv + extra_data), authentication_algorithm): raise InvalidTag("Failed to authenticate data") plaintext = decryptor.update(ciphertext) + decryptor.finalize() if extra_data: return (plaintext, extra_data) else: return plaintext
def encrypt(self, message): iv = urandom(int(self.cipherAlg.block_size / 8)) #generate random iv padder = self.paddingAlg.padder() paddedMessage = padder.update(message) + padder.finalize() #padding encryptor = Cipher(self.cipherAlg, self.mode(iv), default_backend()).encryptor() ct = encryptor.update( paddedMessage) + encryptor.finalize() #encryption ct, iv = b64encode(ct), b64encode(iv) h = HMAC(self.macKey, SHA256(), default_backend()) h.update(ct + iv) mac = h.finalize() #generate MAC return { "ct": ct.decode("ascii"), "iv_nonce": iv.decode("ascii"), "mac": b64encode(mac).decode("ascii") }
def AES_sifrovani(): global s_zprava, b_zprava, p, global_iv if p_symetricky_klic == "": AES_generovani_klicu("p") #Tohle nahradit šifrováním AES b_zprava = Encode(p_zprava) #f = Fernet(p_symetricky_klic) #s_zprava = f.encrypt(b_zprava) iv = os.urandom(12) sifrovani_AES = Cipher(algorithms.AES(p_symetricky_klic), modes.GCM(iv), backend=default_backend()).encryptor() #autorita - asi :/ sifrovani_AES.authenticate_additional_data( b"authenticated but not encrweweweweypted payload") # kvůli gcmku malá zpráva s_zprava = sifrovani_AES.update(b_zprava) + sifrovani_AES.finalize() #print(s_zprava) p = sifrovani_AES.tag global_iv = iv
def decrypt(message: str, receiver_private_key: str) -> str: """ decrypts message @param message: (str) message to decrypt @param receiver_private_key: (str) private key to decrypt with """ message = Bytes.decode_bytes(message.encode('utf-8')) point = message[0:65] tag = message[65:81] ciphertext = message[81:] receiver_private_key_bytes = serialization.load_pem_private_key( receiver_private_key.encode('utf-8'), password=None, backend=default_backend() ) sender_public_numbers = ec.EllipticCurvePublicNumbers.from_encoded_point( ec.SECP256K1(), point) sender_public_key = sender_public_numbers.public_key(default_backend()) shared_key = receiver_private_key_bytes.exchange( ec.ECDH(), sender_public_key ) iv = '000000000000'.encode('utf-8') xkdf = x963kdf.X963KDF( algorithm=hashes.SHA256(), length=32, sharedinfo=''.encode('utf-8'), backend=default_backend() ) key = xkdf.derive(shared_key) decryptor = Cipher( algorithms.AES(key), modes.GCM(iv, tag), backend=default_backend() ).decryptor() dt = decryptor.update(ciphertext) + decryptor.finalize() return Crypt._unpad_data(dt).decode('utf-8')
def _encrypt(self, data: typing.Iterable[bytes]) -> typing.Iterable[bytes]: eprikey = x25519.X25519PrivateKey.generate() epubkey_bytes = eprikey.public_key().public_bytes( encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw) yield epubkey_bytes assert self._PUBKEY_SIZE_BYTES == len(epubkey_bytes) iv = os.urandom(self._IV_SIZE_BYTES) yield iv shared_secret = eprikey.exchange(self._enc_pubkey) cipher_key = self._derive_keys(shared_secret, iv) cipher_iv = iv[:self._CIPHER_IV_SIZE_BYTES] encryptor = Cipher(algorithm=self._CIPHER(cipher_key), mode=GCM(cipher_iv), backend=self._CRYPTO_BACKEND).encryptor() for chunk in data: yield encryptor.update(chunk) yield encryptor.finalize() yield encryptor.tag
def encryptor(key,iv,plaintext): # Construct an AES-GCM Cipher object with the given key and a # randomly generated IV. encryptor = Cipher( algorithms.AES(key), modes.GCM(iv), backend=default_backend() ).encryptor() # associated_data will be authenticated but not encrypted, # it must also be passed in on decryption. # Encrypt the plaintext and get the associated ciphertext. # GCM does not require padding. ciphertext = encryptor.update(plaintext) + encryptor.finalize() tag = encryptor.tag return ciphertext,tag
def aes_encrypt(key, plaintext, associated_data): # Generate a random 96-bit IV. iv = os.urandom(12) # Construct an AES-GCM Cipher object with the given key and a # randomly generated IV. encryptor = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend()).encryptor() # associated_data will be authenticated but not encrypted, # it must also be passed in on decryption. encryptor.authenticate_additional_data(associated_data) # Encrypt the plaintext and get the associated ciphertext. # GCM does not require padding. ciphertext = encryptor.update(plaintext) + encryptor.finalize() #iv = iv.encode('utf-8') #ciphertext = ciphertext.encode('utf-8') tag = encryptor.tag return (iv, ciphertext, tag)
def encrypt( message: object, private_key: str, receiver_public_key: str) -> str: """ encrypts message @param message: (object) message to encrypt @param private_key: (str) private key to encrypt message with @param receiver_public_key: (str) public key of person able to decrypt message """ iv = '000000000000'.encode('utf-8') private_key_bytes = serialization.load_pem_private_key( private_key.encode('utf-8'), password=None, backend=default_backend() ) receiver_public_key = serialization.load_pem_public_key( receiver_public_key.encode('utf-8'), backend=default_backend() ) shared_key = private_key_bytes.exchange(ec.ECDH(), receiver_public_key) point = private_key_bytes.public_key().public_numbers().encode_point() xkdf = x963kdf.X963KDF( algorithm=hashes.SHA256(), length=32, sharedinfo=''.encode('utf-8'), backend=default_backend() ) key = xkdf.derive(shared_key) encryptor = Cipher( algorithms.AES(key), modes.GCM(iv), backend=default_backend() ).encryptor() padded_message = Crypt._pad_data(json.dumps(message)) ciphertext = encryptor.update(padded_message) + encryptor.finalize() complete_ciphertext = point + encryptor.tag + ciphertext return Bytes.encode_bytes(complete_ciphertext).decode('utf-8')
def wrap(self, key, bitsize, cek, headers): rk = self._get_key(key, 'encrypt') if not cek: cek = _randombits(bitsize) # Implement RFC 3394 Key Unwrap - 2.2.2 # TODO: Use cryptography once issue #1733 is resolved iv = 'a6a6a6a6a6a6a6a6' a = unhexlify(iv) r = [cek[i:i + 8] for i in range(0, len(cek), 8)] n = len(r) for j in range(0, 6): for i in range(0, n): e = Cipher(algorithms.AES(rk), modes.ECB(), backend=self.backend).encryptor() b = e.update(a + r[i]) + e.finalize() a = _encode_int(_decode_int(b[:8]) ^ ((n * j) + i + 1), 64) r[i] = b[-8:] ek = a for i in range(0, n): ek += r[i] return {'cek': cek, 'ek': ek}
def decrypt(master_keys, ciphertext_blob, encryption_context): """Decrypt a ciphertext blob using a master key material. NOTE: This is not necessarily what KMS does, but it retains the same properties. NOTE: This function is NOT compatible with KMS APIs. :param dict master_keys: Mapping of a KmsBackend's known master keys :param bytes ciphertext_blob: moto-structured ciphertext blob encrypted under a moto master key in master_keys :param dict[str, str] encryption_context: KMS-style encryption context :returns: plaintext bytes and moto key ID :rtype: bytes and str """ try: ciphertext = _deserialize_ciphertext_blob( ciphertext_blob=ciphertext_blob) except Exception: raise InvalidCiphertextException() aad = _serialize_encryption_context(encryption_context=encryption_context) try: key = master_keys[ciphertext.key_id] except KeyError: raise AccessDeniedException( "The ciphertext refers to a customer master key that does not exist, " "does not exist in this region, or you are not allowed to access.") try: decryptor = Cipher(algorithms.AES(key.key_material), modes.GCM(ciphertext.iv, ciphertext.tag), backend=default_backend()).decryptor() decryptor.authenticate_additional_data(aad) plaintext = decryptor.update( ciphertext.ciphertext) + decryptor.finalize() except Exception: raise InvalidCiphertextException() return plaintext, ciphertext.key_id
def decrypt(self): """Decrypt a blob using LPS. Implements FALLBACK and DP methods to derive or obtain the encryption key from the one stored in the PSE/credential file and then uses that encryption key to decrypt the credential using the AES cipher. LPS-protected PSEs/credentials are verified with both a CRC32 checksum and an HMAC. Validation of the checksum and HMAC is not implemented. :return: decrypted object :rtype: string :raise NotImplementedError: if the LPS method is not implemented :raise SAP_LPS_Decryption_Error: if there's an error decrypting the object """ # Validate supported version if self.version != 2: log_lps.error("Version not supported") raise SAPLPSDecryptionError("Version not supported") # TODO: Calculate and validate CRC32 # Decrypt the encryption key using the LPS method if self.lps_type in lps_encryption_key_decryptor: encryption_key = lps_encryption_key_decryptor[self.lps_type](self) else: log_lps.error("Invalid LPS decryption method") raise SAPLPSDecryptionError("Invalid LPS decryption method") # Decrypt the cipher text with the encryption key iv = "\x00" * 16 decryptor = Cipher(algorithms.AES(encryption_key), modes.CBC(iv), backend=default_backend()).decryptor() plain = decryptor.update(self.encrypted_data) + decryptor.finalize() # TODO: Calculate and validate HMAC return plain
def encrypt_key_attribute(ionic_sep, encrypted_attributes_name, attribute_values_to_encrypt): # To construct encrypted attributes: ## 1. Encode the original values as a JSON array in UTF-8. ## 2. Encrypt the encoded values using `SEP.CD:KS` key under 256-bit AES in GCM with the UTF-8 encoded attribute name used as ## additional authenticated data. The initialization vector should be prepended to the cipher text and the auth tag should ## be appended to the cipher text. ## 3. Encode the result using Base64. ## 4. Add the resulting string as the only value in the list under the attribute name. # 1. Encode the original values as a JSON array in UTF-8. json_array_of_attribute_values_to_encrypt = json.dumps(attribute_values_to_encrypt).encode(encoding='utf-8') # 2. Encrypt the encoded values using `SEP.CD:KS` key under 256-bit AES in GCM with the UTF-8 encoded attribute name used as # additional authenticated data. The initialization vector should be prepended to the cipher text and the auth tag should # be appended to the cipher text. # Create a 16-byte initialization vector of random bytes. attributes_to_encrypt_initialization_vector = os.urandom(16) # Create an AES-GCM cipher using the `SEP.CD:KS` as the key and the 16-byte initialization vector cipher = Cipher(algorithms.AES(ionic_sep.aesCdEiKey), modes.GCM(attributes_to_encrypt_initialization_vector), backend=default_backend() ).encryptor() # Set the authenticated data (AAD) to be the attributes name UTF-8 encoded cipher.authenticate_additional_data(encrypted_attributes_name.encode(encoding='utf-8')) # Encrypt the JSON array of attributes as UTF-8 bytes using 256-bit AES in GCM. attributes_to_encrypt_cipher_text = cipher.update(json_array_of_attribute_values_to_encrypt) + cipher.finalize() # Prepend the 16-byte initialization vector to the cipher text and append the auth tag to the cipher text. ## Prepend the resulting cipher text bytes with the initialization vector. ## Append the auth tag to the resulting cipher text. attributes_to_encrypt_iv_cipher_text_aad_bytes = b''.join([attributes_to_encrypt_initialization_vector, attributes_to_encrypt_cipher_text, cipher.tag]) # 3. Encode the result using Base64 return base64.b64encode(attributes_to_encrypt_iv_cipher_text_aad_bytes)
def __call__(self, fh): iv = self.randomness_source(self.algorithm.block_size / 8) salt = self.randomness_source(16) auth_salt = self.randomness_source(16) key = self.stretch_key(self.key, salt) auth_key = self.stretch_key(self.key, auth_salt) encryptor = Cipher( self.algorithm(key), self.cipher_mode(iv), backend=self.backend, ).encryptor() auth = self.auth( auth_key, self.auth_hash(), backend=self.backend, ) header = self.encode_header(iv, salt, auth_salt) auth.update(header) yield header while True: chunk = fh.read(self.chunk_size) if not chunk: break out = encryptor.update(chunk) auth.update(out) yield out out = encryptor.finalize() auth.update(out) yield out signature = auth.finalize() yield signature
def _decrypt_cryptography(cls, b_salt, b_ciphertext, b_password, key_length): bs = algorithms.AES.block_size // 8 b_key, b_iv = cls._aes_derive_key_and_iv(b_password, b_salt, key_length, bs) cipher = C_Cipher(algorithms.AES(b_key), modes.CBC(b_iv), CRYPTOGRAPHY_BACKEND).decryptor() unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() try: b_plaintext_envelope = unpadder.update( cipher.update(b_ciphertext) + cipher.finalize() ) + unpadder.finalize() except ValueError: # In VaultAES, ValueError: invalid padding bytes can mean bad # password was given raise AnsibleError("Decryption failed") b_plaintext, b_this_sha, b_test_sha = cls._parse_plaintext_envelope(b_plaintext_envelope) if b_this_sha != b_test_sha: raise AnsibleError("Decryption failed") return b_plaintext
def encryptedHandshakeMessage(self, rObj, hObj, kObj, serialize): serialize.extend(uint8(rObj.contentType)) serialize.extend(uint16(rObj.version)) rObj.epoch = 1 serialize.extend(uint16(rObj.epoch)) rObj.seqNumber = 0 serialize.extend(uint48(rObj.seqNumber)) handMessage = self.PRFforHandshake(hObj) self.getKeyFromMaster(hObj, kObj) iv = kObj.client_write_IV encryptor = Cipher(algorithms.AES(kObj.client_write_key), modes.GCM(iv), backend=default_backend()).encryptor() encryptor.authenticate_additional_data(kObj.client_write_MAC_key) ciphertext = encryptor.update(handMessage) + encryptor.finalize() rObj.length = len(ciphertext) serialize.extend(uint16(rObj.length)) serialize.extend(ciphertext)
def encrypt_file(plainpath, cipherpath, password): # Derive key with a random 16-byte salt salt = os.urandom(16) kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend()) key = kdf.derive(password) # Generate a random 96-bit IV. iv = os.urandom(12) # Construct an AES-GCM Cipher object with the given key and IV. encryptor = Cipher( algorithms.AES(key), modes.GCM(iv), backend=default_backend()).encryptor() associated_data = iv + salt # associated_data will be authenticated but not encrypted, # it must also be passed in on decryption. encryptor.authenticate_additional_data(associated_data) with open(cipherpath, "wb+") as fcipher: # Make space for the header (12 + 16 + 16), overwritten last fcipher.write(b"\x00"*(12+16+16)) # Encrypt and write the main body with open(plainpath, "rb") as fplain: for plaintext in iter(lambda: fplain.read(READ_SIZE), b''): ciphertext = encryptor.update(plaintext) fcipher.write(ciphertext) ciphertext = encryptor.finalize() # Always b''. fcipher.write(ciphertext) # For clarity header = associated_data + encryptor.tag fcipher.seek(0,0) fcipher.write(header)
def decrypt(self, token): if not isinstance(token, bytes): raise TypeError("token must be bytes") if not token or six.indexbytes(token, 0) != 0x80: raise InvalidToken hmac = token[-32:] h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend) h.update(token[:-32]) try: h.verify(hmac) except InvalidSignature: raise InvalidToken iv = token[1:17] ciphertext = token[17:-32] decryptor = Cipher(algorithms.AES(self.aes_key), modes.CBC(iv), self.backend).decryptor() plaintext_padded = decryptor.update(ciphertext) try: plaintext_padded += decryptor.finalize() except ValueError: raise InvalidToken plaintext = self.remove_padding(plaintext_padded, algorithms.AES.block_size) try: data_id, = struct.unpack(config.FORMAT_CHAR, plaintext[:8]) except struct.error: raise InvalidToken if data_id == config.DUMMY_ID: raise DummyFileFound data = plaintext[8:] return data_id, data
def encrypt(key=None, iv=None, plaintext=None, debug=0): """ Encrypt the given plaintext using the AES-GCM with the given key and IV. :param key: encryption key :param iv: initialisation vector :param plaintext: data to encrypt :param debug: if 1, prints will be shown during execution; default 0, no prints are shown :return: the ciphertext """ # Check if plaintext is set if plaintext is None: logging.error('sym_encrypt plaintext exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in sym_encrypt plaintext') raise Exception # Check if key is set if key is None: logging.error('sym_encrypt key exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in sym_encrypt key') raise Exception # Check if iv is set if iv is None: logging.error('sym_encrypt IV exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in sym_encrypt IV') raise Exception # Construct an AES-GCM Cipher object with the given key and IV encryptor = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend()).encryptor() # Encrypt the plaintext and return the related ciphertext (GCM does not require padding) return encryptor.update(plaintext)
class AES(object): algorithms = ( 0x0000660e, # AES 128 0x0000660f, # AES 192 0x00006610, # AES 256 ) modes = { "cbc": lambda iv: modes.CBC(iv), "ecb": lambda iv: modes.ECB(), "ctr": lambda nonce: modes.CTR(nonce), } def __init__(self, key, iv=None, mode="cbc"): self.aes = Cipher( algorithms.AES(key), self.modes[mode](iv), backend=default_backend() ).decryptor() def decrypt(self, data): return self.aes.update(data) + self.aes.finalize() @staticmethod def import_key(data): if len(data) < BLOBHEADER.sizeof(): return buf = io.BytesIO(data) header = BLOBHEADER.parse(buf.read(BLOBHEADER.sizeof())) if header.bType not in BlobTypes: return if header.aiKeyAlg not in AES.algorithms: return obj = BlobTypes[header.bType]() obj.parse(buf) return obj.export_key()
def sym_decrypt(key=None, iv=None, ciphertext=None, debug=0): """ Decrypt the ciphertext using AES-GCM with the given key and IV. :param key: decryption key :param iv: initialisation vector :param ciphertext: data to decrypt :param debug: if 1, prints will be shown during execution; default 0, no prints are shown :return: the plaintext """ # Check if key is set if key is None: logging.error('sym_decrypt key exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in sym_decrypt key') raise Exception # Check if iv is set if iv is None: logging.error('sym_decrypt IV exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in sym_decrypt IV') raise Exception # Check if ciphertext is set if ciphertext is None: logging.error('sym_decrypt ciphertext exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in sym_decrypt ciphertext') raise Exception # Construct a Cipher object, with the key, IV and additionally the GCM tag used for authenticating the message decryptor = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend()).decryptor() # Decrypt the ciphertext return decryptor.update(ciphertext)
class Decryptor(object): """Abstract decryption handler. :param algorithm: Algorithm used to encrypt this body :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param bytes key: Raw source key :param bytes associated_data: Associated Data to send to decryption subsystem :param bytes iv: IV value with which to initialize decryption subsystem :param bytes tag: Tag with which to validate ciphertext """ def __init__(self, algorithm, key, associated_data, iv, tag): self.source_key = key # Construct a decryptor object with the given key and a provided IV. # This is intentionally generic to leave an option for non-Cipher decryptor types in the future. self._decryptor = Cipher(algorithm.encryption_algorithm(key), algorithm.encryption_mode(iv, tag), backend=default_backend()).decryptor() # Put associated_data back in or the tag will fail to verify when the _decryptor is finalized. self._decryptor.authenticate_additional_data(associated_data) def update(self, ciphertext): """Updates _decryptor with provided ciphertext. :param bytes ciphertext: Ciphertext to decrypt :returns: Decrypted plaintext :rtype: bytes """ return self._decryptor.update(ciphertext) def finalize(self): """Finalizes and closes _decryptor. :returns: Final decrypted plaintext :rtype: bytes """ return self._decryptor.finalize()
def encrypt(self, value, associated_data: bytes = b'', stash=None): if not value and not isinstance(value, bool): return "" if stash and 'iv' in stash and 'cleartext' in stash and stash['cleartext'] == value: iv = stash['iv'] else: iv = os.urandom(32) # Construct an AES-GCM Cipher object with the given key and a # randomly generated IV. encryptor = Cipher( algorithms.AES(self.key), modes.GCM(iv), ).encryptor() # associated_data will be authenticated but not encrypted, # it must also be passed in on decryption. encryptor.authenticate_additional_data(associated_data) # Encrypt the plaintext and get the associated ciphertext. # GCM does not require padding. ciphertext = encryptor.update(value.encode('utf-8')) + encryptor.finalize() if isinstance(value, str): valtype = 'str' elif isinstance(value, bool): valtype = 'bool' elif isinstance(value, int): valtype = 'int' elif isinstance(value, float): valtype = 'float' else: valtype = 'bytes' return f"ENC[AES256_GCM,data:{b64encode(ciphertext).decode('utf-8')},iv:{b64encode(iv).decode('utf-8')}," \ f"tag:{b64encode(encryptor.tag).decode('utf-8')},type:{valtype}]"
def aes_key_unwrap_with_padding(wrapping_key, wrapped_key, backend): if len(wrapped_key) < 16: raise InvalidUnwrap("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 table_s 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 (b != 0 and not bytes_eq(data[-b:], b"\x00" * b))): raise InvalidUnwrap() if b == 0: return data else: return data[:-b]
def myEncrypt(message, key): if (len(key) < constants.CONST_KEY_BYTES): print("Error: key length less than 32 bytes") return # Creates a random string of 16 bytes iv = os.urandom(constants.CONST_IV_BYTES) # Here we set the parameters for the encryptor # We use AES and CBC encryptor = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()).encryptor() # Encode the message to base64 encoded = base64.b64encode(message) encoded = addPadding(encoded) # We encrypt the message cipherText = encryptor.update(encoded) + encryptor.finalize() return (cipherText, iv)
def _wrap_core( wrapping_key: bytes, a: bytes, r: typing.List[bytes], backend: Backend, ) -> bytes: # 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 encrypt(key, pt, aad): '''AES in GCM Mode encrytion function parameters: key: 128 bit random key pt: plaintext for encryption type: bytes aad: authenticated associated data type: bytes ''' iv = os.urandom(12) # 96 bit initialization vector encryptor = Cipher( algorithms.AES(key), # using AES block cipher modes.GCM(iv), # in GCM mode backend=default_backend()).encryptor( ) # creating a AESGCM cipher object encryptor.authenticate_additional_data( aad ) # authenticated associate data will be authenticated but not encrypted ct = encryptor.update( pt) + encryptor.finalize() # getting cipher text after encryption return (iv, ct, encryptor.tag)
def _unwrap_core( wrapping_key: bytes, a: bytes, r: typing.List[bytes], backend: Backend, ) -> typing.Tuple[bytes, typing.List[bytes]]: # Implement RFC 3394 Key Unwrap - 2.2.2 (index method) decryptor = Cipher(AES(wrapping_key), ECB(), backend).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 decrypt_payload(ciphertext, ciphertext_key, iv, tag, encryption_context={}): """ Decrypt CIS payload using KMS encrypted key. :ciphertext: encrypted payload :ciphertext_key: encrypted KMS derived key :iv: AES initialization vector used to encrypt payload :tag: AES GCM authentication code """ plaintext_key = kms.decrypt( CiphertextBlob=ciphertext_key, EncryptionContext=encryption_context).get('Plaintext') decryptor = Cipher(algorithms.AES(plaintext_key), modes.GCM(iv, tag), backend=default_backend()).decryptor() return decryptor.update(ciphertext) + decryptor.finalize()
def crypto(payload): from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.ciphers import (Cipher, algorithms, modes) from cryptography.hazmat.primitives import padding payload_type = payload[4] decryptor = Cipher(algorithms.AES(keys[payload[4]]), modes.ECB(), backend=default_backend()).decryptor() data = decryptor.update(payload[42:]) unpadder = padding.PKCS7(128).unpadder() unpad = unpadder.update(data) unpad += unpadder.finalize() payload_data = load_packet(unpad) if payload_type == 0x70: if 'key' in payload_data: keys[0x64] = payload_data['key'].encode('ascii') return payload_data
def decrypt(self, fpath, outpath): """ decrypt data file Args: fpath: raw file path outpath: encrpyted file path Returns: None """ with open(fpath, 'rb') as infile, open(outpath, 'wb') as outfile: iv = infile.read(16) decryptor = Cipher(algorithms.AES(self.key), modes.CFB(iv), self.backend).decryptor() for buffer in iter(functools.partial(infile.read, 4096), b''): data = decryptor.update(buffer) outfile.write(data) data = decryptor.finalize() outfile.write(data)
class AES_CTR_cryptography(object): """AES in CTR mode""" block_size = 16 def __init__(self, key, nonce, cnt=0): """initialize AES in ECB mode with the given key and nonce buffer key : 16 bytes buffer nonce: 8 most significant bytes buffer of the counter initial value counter will be incremented starting at 0 cnt : uint64, 8 least significant bytes value of the counter default is 0 """ self.aes = Cipher(algorithms.AES(key), modes.CTR(nonce + pack('>Q', cnt)), backend=_backend).encryptor() def encrypt(self, data): """encrypt / decrypt data with the key and IV set at initialization""" return self.aes.update(data) decrypt = encrypt