So, without further ado, let's get started! To follow this tutorial you'll need an Adafruit Internet of Things Thermal Printer. If you haven't done so already, head on over to http://learn.adafruit.com/pi-thermal-printer/overview and put one together! Then come back and learn a bit about the history of the one time pad, and how to print your own on your IoT printer!
So, without further ado, let's get started! To follow this tutorial you'll need an Adafruit Internet of Things Thermal Printer. If you haven't done so already, head on over to http://learn.adafruit.com/pi-thermal-printer/overview and put one together! Then come back and learn a bit about the history of the one time pad, and how to print your own on your IoT printer!
A Brief History of One Time Pads
Introduction
The Vernam Cipher, or one-time pad, is a cipher that was first invented by Frank Miller in 1882, then later re-invented and patented by Gilbert Vernam in 1919.How It Works
Each character of the message you wish to send (the "plaintext") is combined with one character from the pad (the "key") to produce one character of the coded message (the "ciphertext"). The cipher must also meet the following two conditions:- Each new digit of the key is completely unpredictable.
- The key never repeats, in whole or in part.
Why? Because the key is as long as the message, and all keys are equally likely. Therefore, if the ciphertext is "EQNVZ" then the key could be "XMCKL", which would mean that "HELLO" was the message. Or maybe the key was "TQURI", which would mean that "LATER" was the message. The message could be anything with the same number of characters, and there's no way to tell!
Perfect secrecy! Sound too good to be true? Well... it kind of is. There is a catch that makes this cipher very, very hard to perform in real life. Several, actually, some of which were exploited by this lady:
But that's enough history for now, let's learn how to encrypt and decrypt using a one time pad...
Encryption and Decryption
Encryption
Let's say that the message you want to send is "HELLO". Here are the steps you'd go through:A=01 B=02 C=03 D=04 E=05 F=06 G=07 H=08 I=09 J=10 K=11 L=12 M=13 N=14 O=15 P=16 Q=17 R=18 S=19 T=20 U=21 V=22 W=23 X=24 Y=25 Z=26
Decryption
Decryption works just like encryption, except you subtract instead of adding. Let's say you received a message "AFWXH DDXXL" in your email, and you happen to know that the next pad you're supposed to use is the one with serial "EFXIAKBHAT". Here's the letter conversion table from above, for convenience.A=01 B=02 C=03 D=04 E=05 F=06 G=07 H=08 I=09 J=10 K=11 L=12 M=13 N=14 O=15 P=16 Q=17 R=18 S=19 T=20 U=21 V=22 W=23 X=24 Y=25 Z=26
- First, pop open the container marked EFXIAKBHAT and verify that the pad inside has the same serial.
- Find the page in your pad that starts with "AFWXH".
- D-V=H, D-Y=E, X-L=L, X-L=L, L-W=O.
- The full recovered message is "HELLO".
- Rip out and burn the entire page you were using, even if you didn't use the whole thing.
The Bad News
Ways This Can Get Messed Up
It's time to talk about some of those limitations I mentioned before.- If the key is predictable, even a little bit, you're sunk. That means you can't use real words, anything that you got out of your favorite programming language's rand() function, any algorithm that the NSA has put a back door into, the digits of pi, random numbers out of A Million Random Digits, or anything that has ever been written down publicly. Some Russian spies found that one out the hard way.
- Oh, and "random" numbers you made up in your head or generate by banging on a keyboard aren't random,
either. German and Russian spies found out that one the hard way.
- If you use the key even twice, ever, you're sunk. British, German, Russian, and American spies have all found that one out the hard way. Make sure all copies of the key are destroyed immediately after they have served their purpose, preferably by burning.
- If someone can make a copy of part or all of your pad, you're sunk. What's
worse, if it was your pad that was compromised, you won't have a way of
letting your buddy know that he should stop sending messages with his
copy. You therefore have to have perfect physical control over your copy of the pad at all times. This
is *much* easier said than done. A certain three letter agency has
been known to drill out the lock on your door, photograph everything,
and replace the lock with an identical one in under an hour.
- This algorithm doesn't tolerate error at all. If line noise or an attacker between you and your recipient changes an "E" to an "R", there will be no way for you to know why one letter of your message wouldn't decrypt right.
- Worse, this algorithm doesn't synchronize. So if line noise or an attacker changes an "E" to an "EE", then the entire rest of the message will be totally garbled and totally unrecoverable.
Why Computers Are Especially Awful At This
- The whole point of computers is to make copies of things. Just in the process of generating and printing your one time pads, you will have copies of the pads in memory, on the hard drive, in the system logs, and possibly in the cache of the printer. If your computer is on a network, any one of those copies could silently leak out.
- Even if your computer isn't on a network, it can still wirelessly transmit data. That delivery truck that's been sitting outside for the past hour can use an antenna to listen to the electromagnetic noise that your keyboard or monitor is creating, and use it to figure out what you are typing. You should therefore only operate your printer inside of a faraday cage or in a secure location with plenty of space between you and the public.
- Even if the attacker has to physically break in and steal the hard
drive out of your machine, and you've already deleted everything, you
might still be hosed. When you delete something, it's not really gone. Your computer just forgets where it is, and that space will be reclaimed next time you have a file that needs to go there. Be sure to securely delete any files you make by overwriting the data with all zeros.
- Even if the attacker can't recover any old data, he can still alter
the program that generates the pads to make it output the digits of pi
after a certain offset. You would have no way of knowing that your pads
weren't random. You therefore have to have complete physical control over the computer as well.
The Good News
Why the Raspberry Pi Is Actually Pretty OK For This
- The Raspberry Pi is small. It can be locked in a safe when not in use, or even locked inside of a small faraday cage while in use.
- The Raspberry Pi is cheap. Even if you're totally paranoid, and want to destroy both the SD card and the Pi once you're done generating pads, you wouldn't be out an unreasonable amount of money.
- The Raspberry Pi has a hardware random number generator on it. This. Is. BIG. This means that, with no additional hardware, you can put the Pi to work generating truly random numbers, and doing it fast. Most computers only have software pseudo-random number generators, and therefore cannot be used to generate one time pads.
- Thermal paper printers do not secretly encode the timestamp and serial number of the printer you used onto every print like laser printers do.
The Code
Get It
Once you've got your IoT printer all set up, we're going to need to do a bad thing and hook it up to a network so we can download some code. Head on over to GitHub, and clone the repo onto your local box. To do that, ssh into the pi and run the following command from somewhere in your home directory:git clone https://github.com/iworkinpixels/otp-gen.git
Read It
Here's a quick tour through the code:- otp.sh is a bash script that will generate random numbers, and dump the final one time pad to a text file. This text file will later be sent to the printer every time you press the button on the IoT printer. It runs on every startup, so you should have a new pad every time you start up the printer. Make sure that this is the case, because you can't use the same pad twice.
- otp.py is the python script that gets run when you start up your IoT printer. It listens to the button and prints a copy of the otp text file every time you press the button, and shuts down the pi if you hold down the button.
- otp.txt is an example of the text file that has the one time pad in it. Open it up if you want to take a look without wasting paper. The real otp.txt is written to a ramdisk so that it never goes to the SD card, and is therefore destroyed whenever you shut off the box.
Enable it
First, we need to enable the hardware random number generator. Make sure you are using the appropriate commands for the version of the Raspberry Pi you are using.
Raspberry Pi v1 & v2
Enable the random number generator module:
sudo modprobe bcm2708-rng
This will add the driver for the rng once, but if we want it to show up again after we reboot, we need to add it to /etc/modules-load.d using the following command:
echo bcm2708-rng | sudo tee /etc/modules-load.d/rng-tools.conf
Raspberry Pi v3
Enable the random number generator module:
sudo modprobe bcm2835_rng
This will add the driver for the rng once, but if we want it to show up again after we reboot, we need to add it to /etc/modules-load.d using the following command:
echo bcm2835_rng | sudo tee /etc/modules-load.d/rng-tools.conf
sudo apt-get install rng-tools
Test It
Let's test it out and see if everything works! go to wherever you downloaded the otp-gen repo to, and run the following command:./otp.sh
sudo nano otp.txt
EFXIAKBHAT 1/10 AFWXH VYLLW CJHZA WWHCF VAEAI FWXXQ ARLFU GFCTG MAZSY EHBGP OUVHS FQLBM DGIXN TLHTZ RMFLN CCVDN IKQIZ XKZCC UZFZH RVBGX PQLKC XFHHK MEKHQ HDEJL RPKIK TTZEX JNAXJ MJXCW AGVIS DKUZJ VYTQU LUVID HXCTE XWFXA PAGKH IYXQK LYBJN JQJCV YLOGP VJJUP -------------------------------- EFXIAKBHAT 2/10 JPMVQ FSMCY WLWVH YBIVR HGQHH FKUAZ YIALB EVIIW IPUEL LESFN TJQRJ GYDXT JFYJI UXQPM HTQDU TCGDY UZCGS WFSRT KMQPJ MBEAJ KZQQC LHLPS XMERF IHRMB RWSDM LDVAY TUOWM TUIIP FZSZG NCKBJ PXCUR XMZHZ OVEAP EIJZK YWIDY FPTAA HXQZC XAUQN FYKEZ FDNTG -------------------------------- [...] EFXIAKBHAT 10/10 PADNW MQGYF PAJMU GCVHK YYEFY YIAVW SPIRE IMIPQ ILWJU BTKNH CNFFF QSXTG AFGBC WIJCU DOPJP HMLLY HCZIR RMSTQ ZRUDR NXMFS QMOGV RJGKC JTJXY MINUZ QMEPB EAYYC GHDJF EVAHM ZKRYI VXNUA GERDJ FPRZX SIRKO XPCAD WHJHW JNLXS OCMAR BGHRU NBXQB SFCMP --------------------------------
Deploy It
Assuming everything worked, there's only one step left... we have to hook everything up so it runs when the machine starts!sudo nano /etc/rc.local
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi cd /home/pi/otp-gen ./otp.sh python ./otp.py & exit 0
And that's it! Let's reboot the pi!
sudo shutdown -r now
Every time you press the button after that point, one copy of the pad will be printed. If everything works, then congratulations! You now have a stand-alone one time pad generator. You'll have to find a secure way of getting one copy of the pad to each of your friends, but if you can, then you'll have lots of fun sending super secret messages using state of the art (in WWII) technology!
Next up, security!
Securing The System
- Take it off the network! Your pi no longer has any reason to have a wireless connection, and while it has one, that wireless connection is one giant security hole.
- When it's not in use, stick the whole thing inside a safe.
- If you add a battery for a power supply, it never has to leave the safe. If you line the inside of the safe with copper mesh, the safe doubles as a faraday cage. You open the door, turn on the machine, and press the button. Close the door, wait a few minutes, and open it up.
- Each copy of the pad should be stored in a tamper-resistant container. If you have access to a 3D printer, this one will work well. Edit the OpenSCAD to specify the serial number of the pad you've just generated (it's on the top left corner of every page). Pause the print just before the top starts to print, and insert one tightly-rolled copy of the pad. Then resume the print and you will have a copy of the pad sealed inside. The only way to get it out and read it is to break open the container. Also, secretly reading the pad and then putting it into a replacement container takes time.
- Make two containers, and give one to your friend. When encoding messages, add the serial number, and then the first 5 random letters on the page to the beginning of your ciphertext. That way your recipient will know which container to break open in order to decode the message. When he's done, he should place the remaining pages in another tamper-proof container, or burn them all.
- If you're into 3D design, why not add a loop to the top of the container, and wear it as a necklace? You're a lot closer to having physical control of the pad at all times if you have it physically on you at all times.
- Have a secret, known only to you and your friend, that is used somewhere in every message. For instance, you might agree to use an onomatopoeia, such as "bang" or "buzz" in every message. If someone steals his pad and uses it to send you a message, you will know, because they won't include the secret. Even if they know there's a secret, they hopefully won't know which one it is, because it's never the same word or in the same place in any two messages.
- Note that if someone steals your buddy's copy of the pad, there is no protection for the messages you send him. The attacker can now read everything you send him.
This guide was first published on Aug 15, 2013. It was last updated on Aug 15, 2013.