def generate_key(secret: bytes, prefix: bytes): h = hmac.HMAC(prefix, hashes.SHA256(), backend=default_backend()) h.update(secret) return h.finalize()
def hmac_test(backend, algorithm, params): msg, md, key = params h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) h.update(binascii.unhexlify(msg)) assert h.finalize() == binascii.unhexlify(md.encode("ascii"))
def decrypt(self, ctx, sender_name, verfiy_also=True): """ Decrypt the ciphertext ctx, using receiver's encryption_priv_key and verify signature using sender's signing_pub_key. Which encryption key to use, and which verification key to use is specified in the ciphertext. """ if isinstance(ctx, str): ctx = bytes(ctx, 'utf-8') ctx_list = ctx.split(b'|') [ adata_b64, enc_algorithm, R_encrypted_b64, msg_encrypted_b64, sig_algorithm_b64, signature_b64, hmac_b64 ] = ctx_list logging.debug('Parsed ciphertext') if b'rsa.2048.1' not in enc_algorithm: raise UnsupportedAlgorithm if b'rsa_with_sha256.2048.1' not in base64.urlsafe_b64decode( sig_algorithm_b64): raise UnsupportedAlgorithm # Loading sender's private encryption key sender_enc_priv_key_string = self.deserialize( self.local_private_key_ring['rsa.2048.1.enc.priv']) sender_enc_priv_key = serialization.load_pem_private_key( bytes(sender_enc_priv_key_string, 'utf-8'), password=None, backend=default_backend()) logging.debug('Loaded sender\'s private encryption key') # Loading sender's public signing key for signature verification sender_public_keys = self.import_pub_keys(sender_name, self.remote_public_keyrings) sender_sig_pub_key_string = self.deserialize( sender_public_keys['rsa.2048.1.sig.pub']) sender_sig_pub_key = serialization.load_pem_public_key( bytes(sender_sig_pub_key_string, 'utf-8'), backend=default_backend()) # Asymmetrically decrypt {R} back to (R_sym || R_hmac) R_encrypted = base64.urlsafe_b64decode(R_encrypted_b64) R = sender_enc_priv_key.decrypt( R_encrypted, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) R_sym, R_hmac = R[:32], R[32:] logging.debug('Decrypted R = (R_sym || R_hmac)') # Verify HMAC h = hmac.HMAC(R_hmac, hashes.SHA256(), backend=default_backend()) h.update(adata_b64 + b'|' + msg_encrypted_b64 + b'|' + sig_algorithm_b64 + b'|' + signature_b64) h.verify(base64.urlsafe_b64decode(hmac_b64)) logging.debug('Verified HMAC') # Symetrically decrypt {msg} iv = b'\x00' * 16 msg_encrypted = base64.urlsafe_b64decode(msg_encrypted_b64) decryptor = ciphers.Cipher(ciphers.algorithms.AES(R_sym), ciphers.modes.CTR(iv), backend=default_backend()).decryptor() msg = decryptor.update(msg_encrypted) + decryptor.finalize() logging.debug('Decrypted {msg}') # Verifying signature signature = base64.urlsafe_b64decode(signature_b64) verifier = sender_sig_pub_key.verifier( signature, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) verifier.update(msg) verifier.verify() logging.debug('Decrypted signature') return msg
def _hmac(self): return hmac.HMAC(self._salt, self._algorithm, self._backend)
def _extract(self, key_material: bytes) -> bytes: h = hmac.HMAC(self._salt, self._algorithm, backend=self._backend) h.update(key_material) return h.finalize()
def calculateHash(self, index, previousHash, data, key): h = hmac.HMAC(key, hashes.SHA256(), backend=default_backend()) value = str(index) + str(previousHash) + str(data) h.update(value.encode('utf-8')) nextHash = h.finalize() return nextHash
def _hmac_setup(self, key, payload): h = hmac.HMAC(key, self.hashfn, backend=self.backend) h.update(payload) return h
def test_unsupported_hash(self, backend): with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH): hmac.HMAC(b"key", DummyHashAlgorithm(), backend)
def hmac_sha256(key, msg): mac = hmac.HMAC(key, hashes.SHA256(), default_backend()) mac.update(msg) return mac.finalize()
def test_hmac_reject_unicode(self, backend): h = hmac.HMAC(b"mykey", hashes.SHA1(), backend=backend) with pytest.raises(TypeError): h.update("\u00FC") # type: ignore[arg-type]
def test_verify_reject_unicode(self, backend): h = hmac.HMAC(b"", hashes.SHA1(), backend=backend) with pytest.raises(TypeError): h.verify("") # type: ignore[arg-type]
# FASE 1 - Encriptar # Abrir o ficheiro a cifrar. textofile = open('texto.txt', 'rb') textoCifrar = textofile.read() textofile.close() # Algoritmo Chacha20 para a cifragem. algorithm = algorithms.ChaCha20(chaveC, nonce) cipher = Cipher(algorithm, mode=None, backend=default_backend()) encryptor = cipher.encryptor() mensagemEncriptada = encryptor.update(textoCifrar) # Parte HMAC. mac = hmac.HMAC(chaveMAC, hashes.SHA256(), backend=default_backend()) mac.update(textoCifrar) tagMAC = mac.finalize() mensagemFinal = tagMAC + mensagemEncriptada # Guardar a tag MAC e o criptograma. fileCrypt = open('textoCrypt.txt', 'wb') fileCrypt.write(mensagemFinal) fileCrypt.close() # FASE 2 - Desencriptar decryptor = cipher.decryptor() desencriptado = decryptor.update(mensagemFinal[32:])
def hmac_sha1(key, message): from cryptography.hazmat.primitives import hashes, hmac from cryptography.hazmat.backends import default_backend hasher = hmac.HMAC(key, hashes.SHA1(), backend=default_backend()) hasher.update(message) return hasher.finalize()
def hmacserver (keymac,ct): h = hmac.HMAC(keymac, hashes.SHA256(), backend=default_backend()) h.update(ct) final = h.finalize() return final
def hashing_process(factors_to_hash, hash_iv): for _hash in [hashes.SHA256]: h = hmac.HMAC(hash_iv, hashes.SHA256(), backend=default_backend()) h.update(factors_to_hash) msg_digest = h.finalize() return msg_digest
def cryptography_symmetric_encrypt(encrypt_key, plaintext): """ Encrypt the provided plaintext using AES encryption. NOTE 1: This function return a string which is fully compatible with Keyczar.Encrypt() method. NOTE 2: This function is loosely based on keyczar AESKey.Encrypt() (Apache 2.0 license). The final encrypted string value consists of: [message bytes][HMAC signature bytes for the message] where message consists of [keyczar header plaintext][IV bytes][ciphertext bytes] NOTE: Header itself is unused, but it's added so the format is compatible with keyczar format. """ assert isinstance(encrypt_key, AESKey), 'encrypt_key needs to be AESKey class instance' assert isinstance(plaintext, (six.text_type, six.string_types, six.binary_type)), \ 'plaintext needs to either be a string/unicode or bytes' aes_key_bytes = encrypt_key.aes_key_bytes hmac_key_bytes = encrypt_key.hmac_key_bytes assert isinstance(aes_key_bytes, six.binary_type) assert isinstance(hmac_key_bytes, six.binary_type) if isinstance(plaintext, (six.text_type, six.string_types)): # Convert data to bytes data = plaintext.encode('utf-8') else: data = plaintext # Pad data data = pkcs5_pad(data) # Generate IV iv_bytes = os.urandom(KEYCZAR_AES_BLOCK_SIZE) backend = default_backend() cipher = Cipher(algorithms.AES(aes_key_bytes), modes.CBC(iv_bytes), backend=backend) encryptor = cipher.encryptor() # NOTE: We don't care about actual Keyczar header value, we only care about the length (5 # bytes) so we simply add 5 0's header_bytes = b'00000' ciphertext_bytes = encryptor.update(data) + encryptor.finalize() msg_bytes = header_bytes + iv_bytes + ciphertext_bytes # Generate HMAC signature for the message (header + IV + ciphertext) h = hmac.HMAC(hmac_key_bytes, hashes.SHA1(), backend=backend) h.update(msg_bytes) sig_bytes = h.finalize() result = msg_bytes + sig_bytes # Convert resulting byte string to hex notation ASCII string result = binascii.hexlify(result).upper() return result
def process(self, msg=b""): """ Processa uma mensagem (`bytestring`) enviada pelo SERVIDOR. Retorna a mensagem a transmitir como resposta (`None` para finalizar ligação) """ self.msg_cnt += 1 p = 99494096650139337106186933977618513974146274831566768179581759037259788798151499814653951492724365471316253651463342255785311748602922458795201382445323499931625451272600173180136123245441204133515800495917242011863558721723303661523372572477211620144038809673692512025566673746993593384600667047373692203583 g = 44157404837960328768872680677686802650999163226766694797650810379076416463147265401084491113667624054557335394761604876882446924929840681990106974314935015501571333024773172440352475358750668213444607353872754650805031912866692119819377041901642732455911509867728218394542745330014071040326856846990119719675 pn = dh.DHParameterNumbers(p, g) parameters = pn.parameters(default_backend()) if self.msg_cnt == 1: #envia certificadoA cert_pem = open("Cliente1.p12", "rb").read() self.pk12 = OpenSSL.crypto.load_pkcs12(cert_pem, passphrase=b'1234') self.certificado_cliente = self.pk12.get_certificate() self.PrivateK_assinatura = self.pk12.get_privatekey() cert = OpenSSL.crypto.dump_certificate(FILETYPE_PEM, self.certificado_cliente) return cert if self.msg_cnt == 2: #envia chave publica gx serializada:gxb e recebe certificado servidor #abre o root certificado root_cert1 = open("CA.crt", "rb").read() loadd = OpenSSL.crypto.load_certificate(FILETYPE_PEM, root_cert1) root_cert = OpenSSL.crypto.dump_certificate(FILETYPE_PEM, loadd) self.cert_read = OpenSSL.crypto.load_certificate(FILETYPE_PEM, msg) trusted_cert = OpenSSL.crypto.load_certificate( FILETYPE_PEM, root_cert) # Create and fill a X509Sore with trusted certs store = crypto.X509Store() store.add_cert(trusted_cert) # Create a X590StoreContext with the cert and trusted certs # and verify the the chain of trust store_ctx = crypto.X509StoreContext(store, self.cert_read) result = store_ctx.verify_certificate() if result is None: self.x_client_private_key = parameters.generate_private_key() self.gx = self.x_client_private_key.public_key() self.gxb = self.gx.public_bytes( encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo) self.keyass = self.cert_read.to_cryptography() self.PublicK_assinatura = self.keyass.public_key() return self.gxb else: return False elif self.msg_cnt == 3: #Cliente recebe msg. Que contém gyb e Sigb self.gyb, self.sigb = msg[:-256], msg[-256:] #desserializar chave gyb para gy self.gy = serialization.load_der_public_key( data=self.gyb, backend=default_backend()) ''' :::::::::::::::::::::SIGa(gx,gy):::::::::::::::::::::::::::::::::::: ''' self.assinatura = self.gxb + self.gyb #gxb é a chave da alice enviada, gyb é a chave do bob recebida #vamos fazer a assinatura da chave publica serializada Diffi-Helman da Alice self.signature = self.PrivateK_assinatura.to_cryptography_key( ).sign( self.assinatura, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) ''' VERIFICAR ASSINATURA ''' #self.sigb é a assinatura do servidor, recebida na msg try: self.PublicK_assinatura.verify( # self.sigb, self.assinatura, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) self.shared_key = self.x_client_private_key.exchange(self.gy) except (InvalidSignature): print("Oops! Não se verificou a assinatura.") self.derived_key = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data', backend=default_backend()).derive( self.shared_key) self.key1 = self.derived_key[:16] self.key2 = self.derived_key[16:] print('Input message to send (empty to finish)') new_msg = input().encode() iv = os.urandom(16) cipher = Cipher(algorithms.AES(self.key1), modes.CTR(iv), default_backend()) encryptor = cipher.encryptor() ct = encryptor.update(new_msg) + encryptor.finalize() # mac h = hmac.HMAC(self.key2, hashes.SHA256(), default_backend()) h.update(ct) tag = h.finalize() new_msg2 = (iv + ct) + tag + self.signature return new_msg2 if len(new_msg) > 0 else None elif self.msg_cnt > 3: if msg: criptoIV, tag = msg[:-32], msg[-32:] iv, cripto = criptoIV[:16], criptoIV[16:] h = hmac.HMAC(self.key2, hashes.SHA256(), default_backend()) h.update(cripto) try: h.verify(tag) cipher = Cipher(algorithms.AES(self.key1), modes.CTR(iv), default_backend()) decryptor = cipher.decryptor() msg = decryptor.update(cripto) + decryptor.finalize() print('Received (%d): %r' % (self.msg_cnt, msg.decode())) except (InvalidSignature): print( "Oops! Não se verificou a integridade do criptograma." ) print('Input message to send (empty to finish)') new_msg = input().encode() iv = os.urandom(16) cipher = Cipher(algorithms.AES(self.key1), modes.CTR(iv), default_backend()) encryptor = cipher.encryptor() ct = encryptor.update(new_msg) + encryptor.finalize() # mac h = hmac.HMAC(self.key2, hashes.SHA256(), default_backend()) h.update(ct) tag = h.finalize() # como mandar tag para o outro lado?? new_msg2 = (iv + ct) + tag return new_msg2 if len(new_msg) > 0 else None
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes, hmac key = b"correctHorseBatteryStaple" h = hmac.HMAC(key, hashes.SHA256(), backend=default_backend()) h.update(b"hello world") print(h.finalize().hex())
def _NewHMAC(self, use_sha256=False): if use_sha256: hash_algorithm = hashes.SHA256() else: hash_algorithm = hashes.SHA1() return hmac.HMAC(self.key, hash_algorithm, backend=openssl.backend)
def hmac_sha1(key, message): hasher = hmac.HMAC(key, hashes.SHA1(), backend=default_backend()) hasher.update(message) return hasher.finalize()
def _encrypt(key_data, derived_key_information): """ Encrypt 'key_data' using the Advanced Encryption Standard (AES-256) algorithm. 'derived_key_information' should contain a key strengthened by PBKDF2. The key size is 256 bits and AES's mode of operation is set to CTR (CounTeR Mode). The HMAC of the ciphertext is generated to ensure the ciphertext has not been modified. 'key_data' is the JSON string representation of the key. In the case of RSA keys, this format would be 'securesystemslib.formats.RSAKEY_SCHEMA': {'keytype': 'rsa', 'keyval': {'public': '-----BEGIN RSA PUBLIC KEY----- ...', 'private': '-----BEGIN RSA PRIVATE KEY----- ...'}} 'derived_key_information' is a dictionary of the form: {'salt': '...', 'derived_key': '...', 'iterations': '...'} 'securesystemslib.exceptions.CryptoError' raised if the encryption fails. """ # Generate a random Initialization Vector (IV). Follow the provably secure # encrypt-then-MAC approach, which affords the ability to verify ciphertext # without needing to decrypt it and preventing an attacker from feeding the # block cipher malicious data. Modes like GCM provide both encryption and # authentication, whereas CTR only provides encryption. # Generate a random 128-bit IV. Random bits of data is needed for salts and # initialization vectors suitable for the encryption algorithms used in # 'rsa_keys.py'. iv = os.urandom(16) # Construct an AES-CTR Cipher object with the given key and a randomly # generated IV. symmetric_key = derived_key_information['derived_key'] encryptor = Cipher(algorithms.AES(symmetric_key), modes.CTR(iv), backend=default_backend()).encryptor() # Encrypt the plaintext and get the associated ciphertext. # Do we need to check for any exceptions? ciphertext = encryptor.update( key_data.encode('utf-8')) + encryptor.finalize() # Generate the hmac of the ciphertext to ensure it has not been modified. # The decryption routine may verify a ciphertext without having to perform # a decryption operation. symmetric_key = derived_key_information['derived_key'] salt = derived_key_information['salt'] hmac_object = hmac.HMAC(symmetric_key, hashes.SHA256(), backend=default_backend()) hmac_object.update(ciphertext) hmac_value = binascii.hexlify(hmac_object.finalize()) # Store the number of PBKDF2 iterations used to derive the symmetric key so # that the decryption routine can regenerate the symmetric key successfully. # The PBKDF2 iterations are allowed to vary for the keys loaded and saved. iterations = derived_key_information['iterations'] # Return the salt, iterations, hmac, initialization vector, and ciphertext # as a single string. These five values are delimited by # '_ENCRYPTION_DELIMITER' to make extraction easier. This delimiter is # arbitrarily chosen and should not occur in the hexadecimal representations # of the fields it is separating. return binascii.hexlify(salt).decode() + _ENCRYPTION_DELIMITER + \ str(iterations) + _ENCRYPTION_DELIMITER + \ hmac_value.decode() + _ENCRYPTION_DELIMITER + \ binascii.hexlify(iv).decode() + _ENCRYPTION_DELIMITER + \ binascii.hexlify(ciphertext).decode()
def decrypt_tls_pkt(self, tls_pkt, **kargs): # scapy screws up and changes the first byte if it can't decrypt it # from 22 to 23 (handshake to application). Check if this happens and fix packet_type = tls_pkt.type tls_pkt_bytes = raw(tls_pkt) tls_pkt_bytes = struct.pack("!B", packet_type) + tls_pkt_bytes[1:] print('type:', tls_pkt.type) # STUDENT TODO """ 1. The beginning of this function, already provided, extracts the data from scapy 2. Do the TLS decryption process on tls_pkt_bytes 3. Technically, you don't have to do the hmac. wget will do it right 4. But if you check the hmac, you'll know your implementation is correct! 5. return ONLY the decrypted plaintext data 6. NOTE: When you do the HMAC, don't forget to re-create the header with the plaintext len! """ # need to account for message header type_val = struct.pack('!b', tls_pkt_bytes[0]) version_val = tls_pkt_bytes[1:3] ciphertext_len = tls_pkt_bytes[3:5] print('length of ciphertext:', int.from_bytes(ciphertext_len, byteorder='big')) tls_pkt_bytes = tls_pkt_bytes[5:] # get IV and create decryptor object iv = tls_pkt_bytes[:16] aes = algorithms.AES(self.read_enc) mode = modes.CBC(iv) cipher = Cipher(aes, mode, default_backend()) decryptor = cipher.decryptor() # decrypt ciphertext ciphertext = tls_pkt_bytes[16:] decrypted_pkt = (decryptor.update(ciphertext) + decryptor.finalize()) # print(type(decrypted_pkt[-1])) # padding = int.from_bytes(decrypted_pkt[-1], byteorder='big') padding = decrypted_pkt[-1] # remove padding from decrypted packet # print('padding bytes:',decrypted_pkt[(-1 * padding - 1):]) decrypted_pkt = decrypted_pkt[:(-1 * padding - 1)] # print('decrypted packet:', decrypted_pkt) # extract plaintext + hmac from decrypted ciphertext (remove padding) plaintext_bytes = decrypted_pkt[:-1 * self.mac_key_size] # get hmac value from plaintext + hmac hashed_val = decrypted_pkt[-1 * self.mac_key_size:] # compare hmac sent in packet to our own computed hmac hmac = crypto_hmac.HMAC(self.read_mac, hashes.SHA1(), default_backend()) hmac.update( struct.pack('!q', self.read_seq_num) + type_val + version_val + struct.pack('!h', len(plaintext_bytes)) + plaintext_bytes) new_hashed_val = hmac.finalize() if new_hashed_val != hashed_val: # print('sequence num:', self.read_seq_num) # print('type_val:', type_val) # print('version_val', version_val) # print('len plaintext bytes:', len(plaintext_bytes)) # print('plaintext:', plaintext_bytes) # print(struct.pack('q', self.read_seq_num) + type_val + version_val + struct.pack('h', len(plaintext_bytes)) + plaintext_bytes) # print('new hashed val:', new_hashed_val, 'len:', len(new_hashed_val)) # print('old hashed val:', hashed_val, 'len:', len(hashed_val)) raise ValueError("Hashes are not equal!") self.read_seq_num += 1 return plaintext_bytes
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes, hmac import os, scrypt, base64, pickle import sys hkey=os.urandom(16) salt=os.urandom(16) user,pas=raw_input("username"),raw_input("password") sp=scrypt.hash(pas,salt) h = hmac.HMAC(hkey,hashes.SHA512(), backend=default_backend()) h.update(sp) hp = h.finalize() symkey=scrypt.hash(user,pas,buflen=32) stuff={user:{"symkey":base64.b64encode(symkey),"salt":base64.b64encode(salt),"hkey":base64.b64encode(hkey),"hp":base64.b64encode(hp)}} temp={} f=open("data.txt","ab+") file=f.read() f.close() if len(file)!=0: temp=pickle.loads(file) temp.update(stuff) f=open("data.txt","wb") pickle.dump(temp,f) f.close()
def updateMAC(self): h = hmac.HMAC(self.getDecryptedKey(), hashes.SHA512(), backend=default_backend()) h.update(self.getBytesForMAC()) self.mac = h.finalize()
def base_hmac_test(backend, algorithm): key = b"ab" h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) h_copy = h.copy() assert h != h_copy assert h._ctx != h_copy._ctx
def generateHMAC(key,data): h = hmac.HMAC(key, hashes.SHA256(), backend=default_backend()) h.update(data) return h.finalize()
f = open(fileName, "r") plaintext = f.read() f.close() #convert to bytearray plaintextBytes = plaintext.encode('utf-8') # encrypt Kclient under SHA3-256 - THIS IS THE CLIENT KEY encKclientbytes = hashes.Hash(hashes.SHA3_256(), backend=default_backend()) encKclientbytes.update(KclientBytes) encKclientbytes = encKclientbytes.finalize() print("Client: key = <" + encKclientbytes.hex() + ">") sys.stdout.flush() # Tag = HMAC(key, plaintext) tag = hmac.HMAC(encKclientbytes, hashes.SHA3_256(), backend=default_backend()) tag.update(plaintextBytes) tag = tag.finalize() tag = hashes.Hash(hashes.SHA3_256(), backend=default_backend()) tag.update(plaintextBytes) tag = tag.finalize() # encrypt plaintext||tag encText = b"".join([plaintextBytes, tag]) # pad encText using PKCS7 padder = padding.PKCS7(128).padder() padded_data = padder.update(encText) padded_data = padded_data + padder.finalize()
def HMAC(keyM, msg): h = hmac.HMAC(keyM, hashes.SHA256(), backend=default_backend()) #objeto para cifrar h.update(msg) #gravar return h.finalize( ) #finalizacao, nao permite metodos do objeto #aqui gera o tag
def encrypt(self, msg, receiver_name, receiver_enc_pub_key_alias, sender_sign_header, adata='', sign_also=True): """Encrypt the message msg, using the receiver's encryption_pub_key, and generate signature using sender's sender_sign_priv_key. You have to obtain the keys from the private and public key_rings that you passed during creating this PKFernet object. @sender_sign_header looks like "ecdsa_with_sha256.secp224r1.1.sig[ .priv]". The signer has to parse out from this header to obtain signing private key alias and the hashing algorithm to use for signing. """ # Check receiver's encryption public key algorithm if 'rsa.2048.1' not in receiver_enc_pub_key_alias: raise UnsupportedAlgorithm enc_algorithm = b'rsa.2048.1' # Check sender's signing private key algorithm if 'rsa_with_sha256.2048.1' not in sender_sign_header: raise UnsupportedAlgorithm sig_algorithm = b'rsa_with_sha256.2048.1' sig_algorithm_b64 = base64.urlsafe_b64encode(sig_algorithm) # Loading sender's private signing key for signing the message sender_sig_priv_key_string = self.deserialize( self.local_private_key_ring['rsa.2048.1.sig.priv']) sender_sig_priv_key = serialization.load_pem_private_key( bytes(sender_sig_priv_key_string, 'utf-8'), password=None, backend=default_backend()) # Signing the message using the sender's signing private key signer = sender_sig_priv_key.signer( padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) if isinstance(msg, str): msg = bytes(msg, 'utf-8') signer.update(msg) signature = signer.finalize() signature_b64 = base64.urlsafe_b64encode(signature) # Symmetrically encrypting message R_sym = os.urandom(32) iv = b'\x00' * 16 # IV is 256-bit for AES256; sym_encryptor = ciphers.Cipher(ciphers.algorithms.AES(R_sym), ciphers.modes.CTR(iv), backend=default_backend()).encryptor() msg_encrypted = sym_encryptor.update(msg) + sym_encryptor.finalize() msg_encrypted_b64 = base64.urlsafe_b64encode(msg_encrypted) # Creating associated data if isinstance(adata, str): adata = bytes(adata, 'utf-8') adata_b64 = base64.urlsafe_b64encode(adata) # Generating HMAC R_hmac = os.urandom(32) h = hmac.HMAC(R_hmac, hashes.SHA256(), backend=default_backend()) h.update(adata_b64 + b'|' + msg_encrypted_b64 + b'|' + sig_algorithm_b64 + b'|' + signature_b64) hmac_b64 = base64.urlsafe_b64encode(h.finalize()) # Loading receiver's encryption public key for encrypting the symmetric keys receiver_public_keys = self.import_pub_keys( receiver_name, self.remote_public_keyrings) receiver_enc_pub_key_string = self.deserialize( receiver_public_keys['rsa.2048.1.enc.pub']) receiver_enc_pub_key = serialization.load_pem_public_key( bytes(receiver_enc_pub_key_string, 'utf-8'), backend=default_backend()) # Asymmetrically encrypting R = (R_sym || R_hmac) R_encrypted = receiver_enc_pub_key.encrypt( R_sym + R_hmac, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) R_encrypted_b64 = base64.urlsafe_b64encode(R_encrypted) # Ciphertext format: [adata_b64, enc_algorithm, R_encrypted_b64, msg_encrypted_b64, signature_b64, hmac_b64] ctx = b'|'.join([ adata_b64, enc_algorithm, R_encrypted_b64, msg_encrypted_b64, sig_algorithm_b64, signature_b64, hmac_b64 ]) logging.debug('Generated ciphertext:') return ctx
def sign(self, msg, key): h = hmac.HMAC(key, self.algorithm(), default_backend()) h.update(msg) return h.finalize()