I am new to the world of encryption and I was wondering if my solution for encrypting/decrypting data is okay.
When creating this, I referenced the API documentation from PyCryptodome: https://pycryptodome.readthedocs.io/en/latest/src/api.html
For reference, I have a client-server application and it is assumed the sender already knows the host's public key.
- Is it proper to send the session key, nonce, and tag to the host?
- Is there anything vital that I am missing/overlooked?
def send_data(socket, key, data):
enc_session_key, nonce, tag, ciphertext = encrypt_data(key, data)
encapsulated_data = [enc_session_key, nonce, tag, ciphertext]
data = pickle.dumps(encapsulated_data)
stream = bytes(data)
stream_length = len(stream)
socket.sendall(struct.pack("<Q", stream_length))
socket.sendall(stream)
def encrypt_data(key, data):
recipient_key = key
session_key = get_random_bytes(16)
# Encrypt the session key with the public RSA key
cipher_rsa = PKCS1_OAEP.new(recipient_key)
enc_session_key = cipher_rsa.encrypt(session_key)
# Encrypt the data with the AES session key
cipher_aes = AES.new(session_key, AES.MODE_EAX)
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
return enc_session_key, cipher_aes.nonce, tag, ciphertext
def decrypt_data(enc_session_key, nonce, tag, ciphertext):
if not os.path.exists(PRIVATE_PATH):
return None
private_key = RSA.import_key(open(PRIVATE_PATH).read())
# Decrypt the session key with the private RSA key
cipher_rsa = PKCS1_OAEP.new(private_key)
session_key = cipher_rsa.decrypt(enc_session_key)
# Decrypt the data with the AES session key
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
data = cipher_aes.decrypt_and_verify(ciphertext, tag)
return data
Here, send_data() is called passing in the socket, public key of the reciever, and the data they would like to send.
It is assumed decrypt_data() is called after a host recieves the data and calls pickle.loads() to get the list sent from send_data().
Thank you!!