Hot Koehls

The more you know, the more you don’t know

This content is a little crusty, having been with me through 3 separate platform changes. Formatting may be rough, and I am slightly less stupid today than when I wrote it.
30 Jan 2009

Encryption in your software without key pairs

Any discussion of encryption from a programmer’s perspective almost inevitably leads to public key encryption. This elaborate handshaking process ensures a totally private connection between two distinct parties, and is the basis for SSL/TLS encryption. The most common encryption programs are GnuPG and OpenPGP. However, what about when the only party involved is yourself? Ever run into a situation where you’re own software is the only thing encrypting and decrypting a set of files? After all, at some point your code has to read and use both public and private keys. In cases where the sender and recipient are the same party in the same location, the entire benefit of public/private key pairs goes out the window, and all the complex handshaking illustrated above becomes pretty meaningless. Note that I said “same location;” if the data is encrypted on one server, then delivered and decrypted on another, key pairs still offer extra security. A breach on the server using the public key won’t gain the attackers access to the data, as they would still require the private key to decrypt the data. So assuming we have a piece of software that performs encryption and decryption in a single location, it makes sense to use a single key. This single-passphrase encryption is called symmetrical encryption. The problem: the vast majority of encryption discussion out there cover key pairs, or symmetrical on an individual, “one-off” basis. However you can use GPG to perform symmetrical encryption that…

  • Uses strong encryption, like AES 256-bit
  • Does not make any prompts
  • Tucks passphrase safely away from web access (in the case of a web app).
  • Is just as strong as key pairs (assuming you maintain the security of the key)

Enough chatter, here’s the command line call:

gpg --quiet --no-tty --cipher-algo AES256 --passphrase-file /secure/path/.passphrase -c important_file

```
`**--quiet**` and `**--no-tty**`

Ensure that GPG doesn't output anything to the terminal, including errors. These should be added after you've thoroughly tested your setup.
`**--cipher-algo**`

Allows you to choose which encryption method to use. GPG uses CAST5 by default, which is good, but not nearly as strong as AES 256-bit, which we use here by including **AES256** after the parameter.
Using AES256 also allows us to avoid getting the `WARNING: message was not integrity protected` warning message when we decrypt our files. This warning only appears when doing symmetrical encryption using a cipher that's 64 bits or smaller. A cursory web search reveals a lot of people run into this issue. Switching algorithms to AES256 is enough to avoid the problem entirely, as the cipher is now 256 bits in length. Alternatively, you can pass the `--force-mdc` parameter.
`**--passphrase-file**`

Tells GPG that your passphrase is stored in the specified file. You can name this file whatever you want, and locate it wherever you'd like. However, the user under which you perform the encryption must have access to the file. So in the case of a web-based program, you probably need to grant read access to your web server user (e.g. apache or www-data). Read access is all you need, and should be chmod'd to something like 640 or lower. 400 (read only by user) is ideal.
You can further improve the situation with two small extra steps. First, make sure the file sits outside the web root of your site (i.e. not under public_html, www, or whatever). Second, prefix the entire file name with a period. Looking at the example again we see that the file is actually called .passphrase. This only makes Linux consider the file hidden, and thus invisible to typical navigation. But while it isn't true security, a little bit of "security through obscurity" on top proper permissions and location doesn't hurt.
Finally, remember that since you are storing the passphrase in a file, you have almost no limits on the length and complexity of the password. Maximize that benefit by picking a really complex passphrase. No words, upper and lowercase, symbols. Better yet, let GPG do the work for you:
Here's a quick hack for generating a very secure passphrase using GnuPG itself. The passphrase will not be easy to remember or type, but it will be very secure. The hack generates 16 random binary bytes using GnuPG then converts them to base64, again using GnuPG. The final sed command strips out the headers leaving a single line that can be used as a passphrase: ``` gpg --gen-random 1 16 | gpg --enarmor | sed -n 5p ```
You can easily pipe this text directly into your new passphrase file: ``` gpg --gen-random 1 16 | gpg --enarmor | sed -n 5p > /secure/path/.passphrase ```

comments powered by Disqus