How to send encrypted E-mail

This article covers how to send a private message an unencrypted channel, such as E-mail using openssl.

DISCLAIMER: Nobody talks publicly about the capabilities of intelligence agencies to decrypt messages sent using this technology. Users of this technology should be aware that while the consensus of opinion by security experts is that it is secure, it might be breakable by a suitably motivated nation-state.

Overview

The mechanism for transmitting private material is called public key cryptography. With public key cryptography, you generate a pair of keys, one private, one public. Your correspondent also generates a pair of keys. You and your correspondent exchange public keys. When you wish to send a message to your correspondent, you encrypt the message using your correspondent's public key. Your correspondent receives the encrypted message and decrypts with his or her private key. If your correspondent wishes to verify that the message in fact came from you, you can sign the message with your private key and your correspondent can verify that message came from you, because you and only you have the private key.

Insofar as I know, there are no graphical interfaces to openssl, so all of these commands must be entered on the command line.



Procedure

There several steps to establish secure communications over E-mail.

You must first obtain the openssl software. For most linux distributions, this is already included. For Windows users, you can get it from https://www.openssl.org/related/binaries.html Mac OS X can get it using brew.

After you have obtained openssl, you must create a public/private key pair, called a .pem file. There are several ways to do it, but this seems to be simplest:

openssl genrsa -out mykey.pem 2048

For the moment, the consensus is that 2048 bits is plenty secure, but if you are worried about such things, then you can use 4096 bits. You may see 1024 in several tutorials – that is now considered too small. genrsa means generate an RSA key pair. RSA stands for Rivest-Shamir-Adleman, the researchers who invented public key cryptography.

Next, you have to separate the public and private keys.

openssl rsa -in mykey.pem -pubout -out mykey.pub

You then E-mail your public key to your correspondent. The NSA can easily intercept your mail message, for all the good it will do them. Meanwhile, you put your private key some place safe. Your correspondent does the same things, and sends you her public key.

openssl genrsa -out her_key.pem 2048
openssl rsa -in her_key.pem -pubout -out her_key.pub

Create a file, which I am going to call clear.txt, but in fact could be anything you want kept secret: love letters, medical records, child pornography, plans to a nuclear power plant, etc.

echo "The flight speed of a sparrow.  An African sparrow or a European sparrow?  SPROING!  These are the sorts of things you need to know to be a king" > clear.txt

Now we are ready to encrypt file with her public key:

openssl rsautl -encrypt -inkey her_key.pub -pubin -in clear.txt -out encrypt.dat

You may use your favorite plain text editor, such as notepad, vi or emacs to inspect (but do not change) encrypt.dat and verify that it is a hopeless mess.

You now send a mail message to your correspondent, and attach encrypt.dat to it. Your correspondent receives the message, and decrypts it with her private key.

openssl rsautl -decrypt -inkey her_key.pem -in encrypt.dat -out new_clear.txt

Do the transmitted file and the received file match?

diff clear.txt new_clear.txt

They do.

If you want to sign the message, then you can create a digest of the clear text and then encrypt the hash with the private key:

openssl dgst -sha256 clear.txt > hash

openssl rsautl -sign -inkey mykey.pem -keyform PEM -in hash > signature

Your correspondent receives the signature and verifies the text against it, using your public key.  If this works, then your correspondent knows that you sent it, because you are the only one with the private key:

openssl rsautl -verify -inkey mykey.pub -pubin  -in signature
SHA256(clear.txt)= ce6578b79ee8d2819996b57a3cca5d4220ecdfc6f5a8c204062077b3dc7d102a

Now, your correspondent has to calculate the hash of the text you sent her.

openssl dgst -sha256 new_clear.txt
SHA256(new_clear.txt)= ce6578b79ee8d2819996b57a3cca5d4220ecdfc6f5a8c204062077b3dc7d102a

The hashes are the same.  So your correspondent has now verified that the file came from you (or else she wouldn't be able to decode the signature) and that the file has not been tampered with (or else the hashes wouldn't match)