C 431: Public-Key Encryption With Sodium (25 extra)

What You Need

Any machine with Python 3.

Purpose

To learn how to use the Sodium library to perform ECC as a replacement for RSA, as advocated in the video below.

Installing and Importing PyNaCl

In a Terminal window, execute these commands to install the PyNaCl library, launch Python 3 in interactive mode, and import the functions we need:
python3 -m pip install pynacl
python3
import nacl.utils
from nacl.public import PrivateKey, Box

Generating Bob's Keys

Bob needs to generate a key pair: skbob - his secret key, and pkbob - his public key.

Execute these commands:

skbob = PrivateKey.generate()
skbob.encode(encoder = nacl.encoding.HexEncoder)
pkbob = skbob.public_key.encode(encoder = nacl.encoding.HexEncoder)
pkbob
Bob's public and private keys are both long strings of hexadecimal characters, as shown below.

Bob will publish his public key somewhere everyone can find it, such as a Web page, and keep his private key secret.

Generating Alice's Keys

Execute these commands to generate Alice's keys:
skalice = PrivateKey.generate()
pkalice = skalice.public_key.encode(encoder = nacl.encoding.HexEncoder)
pkalice
Alice's public key is a different string of random hexadecimal characters, as shown below.

Alice publishes her public key, just as Bob did.

Encrypting with Box

The Box class uses a private key and another person's public key to derive a shared key, which can be used to send encrypted messages.

Bob wants to send a message "HELLO FROM BOB" to Alice. He needs to encode Alice's public key from hexadecimal into a nacl PublicKey structure.

To do that, execute these commands:

pkalice
decoded_pkalice = nacl.public.PublicKey(pkalice, encoder = nacl.encoding.HexEncoder) 
bob_box = Box(skbob, decoded_pkalice)

plaintext = b"HELLO FROM BOB"
ciphertext = bob_box.encrypt(plaintext).hex()
ciphertext
pkalice is in hexadecimal, and we imported it into a nacl PublicKey structure named decoded_pkalice.

That object, together with Bob's private key, formed the shared secret key needed to create the Box object so we could encrypt the message.

The ciphertext is random-looking bytes, as shown below.

Decrypting

Bob sends the ciphertext to Alice. Alice can decrypt it using her private key and Bob's public key.

Execute these commands:

pkbob
decoded_pkbob = nacl.public.PublicKey(pkbob, encoder = nacl.encoding.HexEncoder) 
alice_box = Box(skalice, decoded_pkbob)
plaintext = alice_box.decrypt(bytes.fromhex(ciphertext))
plaintext
Both ciphertexts decrypt to the same message, as shown below.

C 431.1: Public Key (5 pts)

Larry's private key is:

ec6a35628ce2a22a5580ecf5f0a26c1b9be7fb472ef1ea76fafba8b5fc280d21

Find Larry's Public Key. That's the flag.

C 431.2: Decryption with the Key (20 pts)

Felix has sent you the flag. Find the flag from the information below.
  • Felix's Public Key:
    c211cf597e41c250f895b52cbf56e0c01f843d23cb2aeac14abcf1ed11b9b502

  • Your Public Key:
    97ff076381c5d86915b6780ea3cf299b1de6ca9a52f9445e5f60899fd1f4420f

  • Your Private Key:
    f9a99f5cb3174818e3a46587c8979e737ad823d9d80441881cb8676ae67adbd1

  • Encrypted Message:
    bc24b2be13174ca12f76f4570c1b68334c5e39e32692fdb49f7bf4ddda801c66
    4eec59405f7340de1351188a0ebfe1a62fb737c849ee00d94129858863

Sources

PyNaCl 1.3.0 documentation: Public Key Encryption
'Read the docs' doesn't explain how to import public keys.


Posted 11-13-20