We can use public-key encryption to produce an encrypted box from Bob to Alice. First, we take Bob private key (skbob) and Alice’s public key (pkalice). Bob initially creates a hash of the message, and then encrypts this with his private key (skbob). He will then create a unique symmetric key and encrypt the message and the encrypted hash. He then encrypts the symmetric key with Alice’s public key (pkalice). Alice then receives the box, and decrypts the symmetric key with her private key (skalice). She then can read the message. Next, she checks the hash of the message and then decrypts the encrypted hash with Bob’s public key. If the hashes match, she knows that Bob signed the message with his private key. An outline of this is given next (and where the email encryption key is the symmetric key used). In this case we will use the Networking and Cryptography (NaCl) library, and which uses Curve25519 for the public key part, and 256-bit AES GCM for the symmetric key element.
Sodium: NaCl - Box |
Outline
We can use public-key encryption to produce an encrypted box from Bob to Alice. First, we take Bob private key (skbob) and Alice’s public key (pkalice). Bob initially creates a hash of the message, and then encrypts this with his private key (skbob). He will then create a unique symmetric key and encrypt the message and the encrypted hash. He then encrypts the symmetric key with Alice’s public key (pkalice). Alice then receives the box, and decrypts the symmetric key with her private key (skalice). She then can read the message. Next, she checks the hash of the message and then decrypts the encrypted hash with Bob’s public key. If the hashes match, she knows that Bob signed the message with his private key. An outline of this is given next (and where the email encryption key is the symmetric key used):
and:
Coding
The code is:
import nacl.utils from nacl.public import PrivateKey, Box import binascii import sys mess = "My message" if (len(sys.argv)>1): mess=str(sys.argv[1]) message=mess.encode() skbob = PrivateKey.generate() pkbob = skbob.public_key skalice = PrivateKey.generate() pkalice = skalice.public_key bob_box = Box(skbob, pkalice) encrypted = bob_box.encrypt(message) nonce = nacl.utils.random(Box.NONCE_SIZE) encrypted = bob_box.encrypt(message, nonce) alice_box = Box(skalice, pkbob) plaintext = alice_box.decrypt(encrypted) print(f"Bob public {binascii.b2a_hex(pkbob.encode())}\nBob private {binascii.b2a_hex(skbob.encode())}") print(f"\nAlice public {binascii.b2a_hex(pkalice.encode())}\nAlice private {binascii.b2a_hex(skalice.encode())}") print(f"\nMessage: {message.decode()}\nEncrypted {encrypted.hex()}") print("\nDecrypted: ",plaintext.decode())
A sample run is:
Bob public b'2381c06959418616f2099d3d57be2da1fe150b7392aa73cf9cf83221ea039356' Bob private b'd31dae3baeaf4d2023231d7cd31cb45a5f46f0c6804ef62c086654c3612d2c74' Alice public b'0b9a6fbcdedfea144cbc9c937d1f9945ab2713823b4c0d677174d76a8f886337' Alice private b'7fe9266481a38e3258ceb71745406da6f0bf1a3e9d4515e7e2d1666510182a80' Message: My message Encrypted bbe0af91c897ac430e50c2c6e3d54387e87dd608dc56860e60e40dfd3dc7bcfc32c6da34086ceca9f69594e27a414a5d5aed My message