Table of Contents
NaCL Cryptography Programming Lab
Overview
For this lab, you will be using basic cryptographic functions provided by the Sodium crypto library (libsodium), which is a portable fork of NaCl, the "Not Another Crypto Library" developed by Daniel J. Bernstein (DJB). Libsodium has API bindings for common programming languages beyond C/C++. You can implement the lab in any language you desire, although Python is the suggested language if you want instructor assistance.
Setup
Python 3 setup instructions using PyNaCl wrapper library:
sudo apt-get install python3-pip
sudo apt-get install python3
pip3 install --upgrade pip
pip3 install pynacl
# sudo pip3 install --upgrade pynacl # To upgrade PyNaCl later
C/C++ setup instructions using native Libsodium:
sudo apt-get install build-essentials
wget https://download.libsodium.org/libsodium/releases/LATEST.tar.gz
tar -xzf LATEST.tar.gz
cd libsodium-stable
./configure
make && make check
# Should see following printed after test suite runs: PASS: 70
sudo make install
Other languages
# If you use another language, record your setup instructions and tell me!
Part 1 - One-Time Pad
Professor Shafer wishes to send a message to the class using a one-time pad because it has the property of perfect secrecy.
Two files are provided:
- The encrypted message (originally ASCII text) - part1.ciphertext.bin
- The one-time pad, cryptographically random - part1.otp.bin
Write a Python3 program named part1.py
that reverses the one-time pad and prints the plaintext message to the screen.
Part 2 - Symmetric Key Cryptography
Professor Shafer finds a one-time pad is too cumbersome of a secret to manage and distribute. Instead, he wishes to send a message to the class using symmetric key encryption. He uses the Salsa20 stream cipher with Poly1305 message authentication code provided by the Libsodium library.
Two files are provided:
- The encrypted message (originally ASCII text) - part2.ciphertext.bin
- The symmetric key, cryptographically random - part2.key.bin
Write a Python3 program named part2.py
that decrypts and prints the plaintext message to the screen.
Part 3 - Public Key Cryptography
Professor Shafer doesn't like having to distribute a secret symmetric key to the students to allow them to receive his messages. Instead, he wishes to send a message to the class using public key encryption and only distribute public keys, while keeping his secret key secret. He will use Curve25519 high-speed elliptic curve cryptography to accomplish this.
Your program must transmit to the cyberlab.pacific.edu:12001
server the following payload in a “HTTP-like" format as an ASCII string:
CRYPTO 1.0 REQUEST\r\n
Name: Your Name\r\n
PublicKey: <Base16 string of your public key>\r\n
\r\n
After transmitting a packet to the server, your program must also receive a TCP reply from the server with the following payload:
CRYPTO 1.0 REPLY\r\n
Name: Jeff Shafer\r\n
PublicKey: <Base16 string of Shafer's public key>\r\n
Ciphertext: <Base16 string of ciphertext>\r\n
\r\n
Write a Python 3 program named part3.py
that communicates with the server, receives the ciphertext, and prints the plaintext message to the screen.
Part 4 - Password Storage
Professor Shafer is tired of dealing with keys, and would rather deal with human friendly passwords. He has encrypted his secret data via the following process:
- Use scrypt password-hashing mechanism to produce 32-byte key from password. CPU and memory difficulty levels (iterations) were changed from the default values to
SCRYPT_OPSLIMIT_INTERACTIVE
andSCRYPT_MEMLIMIT_INTERACTIVE
to provide a balance between difficulty and time. - Generate a random key and protect it via symmetric key encryption (Salsa20/Poly1305 MAC) with the password-derived key. This is the "outer box".
- Take the secret payload and protect it via symmetric key encryption with the random key. This is the "inner box". This allows the password to be changed in the future without needing to re-encrypt the entire secret payload.
One file is provided: part4.ciphertext.bin. This encrypted file has been saved to disk in the following format:
- Password salt: 32 bytes
- Outer box, encrypted: 72 bytes (32 byte key + 24 byte nonce + 16 byte auth). The outer box contains the random key
- Inner box, encrypted: Variable length (variable-length payload + 24 byte nonce + 16 byte auth). The inner box contains the secret payload.
Note that this secret payload is NOT ASCII text. Rather, it is mystery data and you should discover what it is using the tools at your disposal.
Ask Professor Shafer for the super secret password to get started.
Write a Python3 program named part4.py
that decrypts the secret payload, saves it to disk, and then opens an appropriate viewer for the data type. Using the Libsodium library (not a standalone utility), compute the SHA-256 hash of the secret payload and print the hash on screen.
Write a Python 3 program named part4_pw_change.py
that allows the user to change the password without needing to re-encrypt the entire payload. Use the new password "cyberlab". The new output file should be named part4.ciphertext-new.bin
.