Bob Sends Alice A Box

I love cryptography. It provides me with an almost infinite field of learning. While I have saturated my knowledge in areas of data…

Photo by rizki rama28 on Unsplash

Bob Sends Alice A Box

I love cryptography. It provides me with an almost infinite field of learning. While I have saturated my knowledge in areas of data communication and network, it is cryptography that provides me with the beauty of maths, but the wonderment of providing the foundation of cybersecurity. With it, we can not only protect the privacy of messages from Bob to Alice, but we can identify that it was only Bob who send the message and that it has not been changed. For the first time in the history of humankind to can properly secure the messages we send.

A secret box

Now let’s say that Bob is a lawyer, and he wants to send a secret message to Alice. He takes a box from his shelf, and which has a unique key. He takes photograph of himself holding the message, and puts it into the box with the photography. Next, he takes a box that Alice send to him and puts the secret key into the box. Now Bob cannot open any of the boxes. He then sends the two boxes to Alice. Alice takes the second box, and sources the key to that box. She opens this box, and it contains the key for the first box, and then opens it. She then reads the message, and check the photography.

So how can we do this in public-key encryption?

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):

We can now implement with NaCl. The code is [here]:

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 [here]:

Bob public b'2381c06959418616f2099d3d57be2da1fe150b7392aa73cf9cf83221ea039356'
Bob private b'd31dae3baeaf4d2023231d7cd31cb45a5f46f0c6804ef62c086654c3612d2c74'
Alice public b'0b9a6fbcdedfea144cbc9c937d1f9945ab2713823b4c0d677174d76a8f886337'
Alice private b'7fe9266481a38e3258ceb71745406da6f0bf1a3e9d4515e7e2d1666510182a80'
Message: My message
Encrypted bbe0af91c897ac430e50c2c6e3d54387e87dd608dc56860e60e40dfd3dc7bcfc32c6da34086ceca9f69594e27a414a5d5aed
 My message

Here is the code:

Conclusions

We live in a 1980s viewpoint of data. Why can’t we decrypt by default? Why can’t we sign for data? Why can’t we check for integrity?