#One Time Pad Utilities
Glen Wiley [email protected]
This is a set of command line utilities for creating and using one time pads for encrypting and decrypting messages.
This approach will seem awkward and inconvenient when you first begin using it, however it is useful to note that strong encryption is by its nature awkward and this is as strong as it gets (when used properly). If you prefer convenience and can settle for breakable encrytpion then you are probably better off with a different tool set.
The only way to compromise this approach is to let someone else have access to your one time pad sheet or to use the same sheet (or portion of a sheet) for more than one message.
If you find yourself wondering whether it is worth the trouble, I recommend that you brush up on cryptography theory and compare one time pad encryption with other approaches.
This project is licensed under the Creative Commons Attribution 3.0 Unported which means you can modify it and use it commercially but I ask that you provide appropriate attribution (give me credit).
#Building and Installing
There are no external dependencies (beyond a modern C compiler). The interface is entirely terminal/CLI based.
#Building
Use the Makefile that matches your operating system, for example on Linux:
# make -f Makefile.linux
# make -f Makefile.linux install
#Recommended Use Cases
##Generate a single sheet
Nearly the simplest way to use the program is:
otpadgen -o matrix > matrix
otpadgen > sheet
You then give a copy of both the matrix and the sheet to your peer, the matrix doesn't change from sheet to sheet but a new sheet should be used for each message.
##Generate a set of sheets
These sheets can be generated then handed to the peer, in order to use them you must agree on which sheet in the set you are using.
otpadgen -o matrix > matrix
dt=$(date)
for((sn=0;sn<10;sn++))
do
otpadgen -h"sheet $sn : $dt" -s abb -o text > sheet$sn
done
##Use otpadmsg to encrypt a message
Given a one time pad sheet (file name 'sheet') that you previously generated and a message file named 'msg' that you would like to encrypt:
# otpadmsg -S sheet -m msg > msg.enc
If you have already given the one time pad sheet to your friend then you may then send msg.enc over a non-secure media to him. Once he receives it the following command will decrypt it:
# otpadmsg -S sheet -m msg.enc > msg
#How to use one time pads
One of the nifty advantages of one time pads is that they can be generated by machine (or even by hand for that matter) and then used to encrypt and decrypt without assistance from a machine. It is certainyl faster if you use a computer to encrypt and decrypt, but it is not difficult to do by hand.
##Host Security The two most important rules of using one time pads to avoid weakening their utility as a cryptographic tool are:
- NEVER reuse a one time pad. There are some cases in which multiple receivers might use the same pad but NEVER encrypt more than one message with the same bytes in the same one time pad.
- NEVER share the one time pad with anyone you do not intend to share the clear text of your message.
It is worth noting that network connected hosts are simply NOT as secure as a machine that has no interface with the outside world. The most secure hosts are completely unreachable (which significantly reduces their utility to legitimate operators). The hosts used to generate the one time pads should be completely isolated from networks and physical access by unauthorized personnel. Yes this is a pain, but if you really want strong crypto then this is simply what you have to do. No matter how strenuously someone might object and say that they are able to secure their host, if there is a network connection of any kind then that host can be compromised.
The character set used to generate the pad is typically just alpha/numeric characters. We include the space as an underscore character. A full alphabet includes a number of the more useful symbols, the downside to these is that when they are handwritten it is easy to make a mistake interpreting what someone else has written.
Choosing how you will write characters (if you are encrypting by hand) is also very important - it is a good idea to make you fours (4) and nines (9) distinct, your sevens (7) and ones (1), zeros (0) and ohs (O).
##How to Encrypt
- Generate your one time pad (otpsheet) and the character matrix and give a copy to your peer
# otpadgen > otpsheet
# otpadgen -o matrix > otpmatrix
- Write your clear text above the characters on the one time pad.
- Encrypt one character at a time using the matrix:
- Find the column headed by the clear text character
- In that column find the row whose character matches the key character
- The first character in the row is your encrypted character, write this under the key on the one time pad sheet
- Once you have done this for all the characters in your message, copy the encrypted characters to a separate sheet of paper - this is the message that you can hand your peer to be decrypted.
- Rejoice at the strength of your cryptography!
##How to Decrypt
- Obtain copies of the one time pad sheet and the character matrix from your peer.
- Write the encrypted message above the key characters on the one time pad.
- Decrypt one character at a time using the matrix:
- Find the column headed by the message character
- In that column fund the row whose character matches the key character
- The first character in the row is your encrypted character, write this under the key on the one time pad sheet
- The characters below the key characters are the decrypted message.
- Glory in the light of your unbreakable message.
Here is an example of looking up the characters using the matrix:
Given the following table segment (this is contrived to keep the demo short):
_ 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
_ | _ 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 | 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ 1 | 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ 0 2 | 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ 0 1 3 | 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ 0 1 2
And given this message text: M U S T _ And given this one time pad: O X T V 0 The encrypted text would be: 1 2 0 1 0
The Decrypt would look like this: Given this encrypted message: 1 2 0 1 0 Given the same OTP used to encrypt: O X T V 0 Results in the cleartext: M U S T _
##otpadgen Command Reference
USAGE: otpadgen [-m] [-H | -h <header>] [-l <linelen>] [-w <wordlen>] [-r <devrand>] [-k <keylen>] [-s <f|a>] [-o <text|num>]
-h <header> print this string as the first line of the output
-H print a generated header string as the first line of the output
-k <keylen> key length in chars
default: 400
-l <linelen> line length in chars, used by text output mode
note that each char needs 2 spaces + word gaps
default: 25
-m character matrix output, no pad is generated
-o text output as simple text (default)
num output as numbers
-r <devrand> device from which to read entropy (as binary stream)
default: /dev/urandom
-s <f|a> character set to use
f = full character set: alpha, digit, punctuation (space=_)
a = abbreviated character set: alpha, digit (space=_)
default: a
-w <wordlen> word length in chars, affects printing only
default: 5
Generate a one time pad that can be used for encrypted message exchanges.
By default a printable format is produced in ASCII text that includes the
following characters for the full set:
_!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
and the following characters for the abbreviated set:
_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
<space> rendered as underscore (the underscore character is not supported)
You will need the character matrix (Vigenere square) to encrypt/decrypt.
How to Encrypt
--------------
1. Generate your one time pad (otpsheet) and the character matrix and give
a copy to your peer
# otpadgen > otpsheet
# otpadgen -o matrix > otpmatrix
2. Write your clear text above the characters on the one time pad.
3. Encrypt one character at a time using the matrix:
- Find the column headed by the clear text character
- In that column find the row whose character matches the key character
- The first character in the row is your encrypted character, write
this under the key on the one time pad sheet
4. Once you have done this for all the characters in your message, copy the
encrypted characters to a separate sheet of paper - this is the message
that you can hand your peer to be decrypted.
5. Rejoice at the strength of your cryptography!
How to Decrypt
--------------
1. Obtain copies of the one time pad sheet and the character matrix from your
peer.
2. Write the encrypted message above the key characters on the one time pad.
3. Decrypt one character at a time using the matrix:
- Find the column headed by the message character
- In that column fund the row whose character matches the key character
- The first character in the row is your encrypted character, write this
under the key on the one time pad sheet
4. The characters below the key characters are the decrypted message.
5. Glory in the light of your unbreakable message.
Here is an example of looking up the characters using the matrix:
Given the following table segment (this is contrived to keep the demo short):
_ 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
-----------------------------------------------------------------------------
_ | _ 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 | 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _
1 | 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ 0
2 | 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ 0 1
3 | 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ 0 1 2
And given this message text: M U S T _
And given this one time pad: O X T V 0
The encrypted text would be: 1 2 0 1 0
The Decrypt would look like this:
Given this encrypted message: 1 2 0 1 0
Given the same OTP used to encrypt: O X T V 0
Results in the cleartext: M U S T _
#One Time Pad Encryption Theory
- http://www.aspheute.com/english/20010924.asp
- http://users.telenet.be/d.rijmenants/en/onetimepad.htm
- http://www.scn.org/~bh162/one-time_pad_encryption.html
#Random number generation
On Linux we default to /dev/urandom for our source of entropy, /dev/random is a better choice, however it will block waiting for entropy if it exhausts the pool. If you want the best entropy from a PRNG on Linux then you should use /dev/random via the "-r" option and wait for it to accumulate enough entropy to generate the one time pad (it will look as though it is hung while it waits).
Weak random number generation will result in weak cryptography. If a mal-actor can predict your random number generator output then they may be able to divine the key you are using for one time pad cryptography. It is very important that you use a reliable source of entropy to generate your pads.
Whole books have been writton on generating true random numbers so I am not going to try to cover the topic to any level of detail here but rather will offer a few thoughts on the most important potential issues. There are two primary vectors for compromise:
- Mal-actors that introduce means with which to reliably predict the output of the RNG
- Mal-actors that leverage side-channel attacks that influence the output of the RNG
We will ignore the third (and arguably most common) vector which is an operator using an RNG not capable of producing entropy.
In order to be able to trust the random number generator (RNG) there must be no "black boxes" in the hardware OR you must truly be willing to trust the folks that built the RNG with the data you are encrypting (as if it were handed to them in the clear). Most modern computers fail to meet this criteria. s they leverage a pseudo RNG - often a very good one, but still a PRNG. They also are FULL of opportunities for a mal-actor to introduce back doors or other means for creating predicatable output from the RNG.
Better sources of entropy are simple hardware devices for which the hardware and software design is fully transparent.
#TODO
- real documentation - there is too much to put in a readme
- fix terms - is this a vignere table rather than matrix
- add automatic checksum
- port to freebsd, osx
- use autoconf/automake ** test for arc4random (avail on osx, not default ubuntu)
- man pages