Encryption: secure at the command line

One of the most difficult issues in encryption is the chain of trust in tools. Let’s say you buy the app SuperEnigmaCrypt from the Mac App Store, intending to use it to encrypt and decrypt very sensitive documents.

In using SuperEnigmaCrypt, you place trust in the developer, that they have correctly implemented the encryption methods which you use, and have not made any errors which might compromise its robustness. If the developer’s name happens to be “GCHQ Cheltenham” (or “CIA, Langley”), you might suspect that what you are getting is not all that it seems to be.

Even if you know the developer to be impeccably trustworthy, they could have made an error in implementation which might compromise the robustness of its encryption; bugs do happen. It is incredibly hard to prove with any degree of confidence that a function as complex as encryption is free of bugs.

It is also most likely that any Mac app will follow Apple’s recommendations to developers, and will not directly call low-level encryption facilities, but use the OS X security libraries. So even if the app developer has got it right, there is also the risk that there could be a bug in your particular release of OS X – again, such bugs are not unheard of.

The shortest and most open chain of trust is for you to use a widely-accepted open source tool: in this case, OpenSSL, which is supplied as part of the normal installation of OS X, but as command shell tools. If you want to be thoroughly distrustful of third parties, you can even download it as source, compile and install it yourself. One snag with OpenSSL is that it is not provided in iOS, but you should either find it already on most other systems, or you can add it if you need.

Using OpenSSL encryption and decryption is not difficult, although the man pages for enc and openssl are quite long and involved. We can simplify this by limiting the options a bit.

First, we will use the AES (Rijndael) algorithm because it remains unbroken and is well tried and tested. For the best level of security, we will use the 256-bit option, which is that recommended for the most secure confidential documents in US government. If or when that gets broken, we should hear about it, and our problems will be nothing compared to those of others.

There are some options over the precise mode in which to use AES (something I will explore in a future article): the CBC mode is standard in most applications and should suffice here.

For this example, we will supply the password direct to the encrypt and decrypt commands, rather than accessing anything in keychains or files. Although this leaves the password visible in Terminal, it is not hard to clear that away, and there is no risk that something could gain access to our keychain and discover the password from there.

Good practice is to use the password with ‘salt’, a random hexadecimal number of up to 16 digits, which will be used together with our password to generate the key for encryption. For the moment I will not consider further how we might generate that salt, and we should not have to provide it for decryption.

Putting this altogether into a shell command you can enter in Terminal, the components are:

  • openssl the command itself
  • aes-256-cbc the encryption to be used, 256-bit, CBC mode
  • -e to encrypt, -d to decrypt
  • -salt to require the use of ‘salt’ when encrypting
  • -S to provide the hexadecimal ‘salt’ to be used; for this example I will use FFFFFFFFFFFFFFFF but you will need to use a random number given in similar hex form
  • -a to encode the encrypted file in Base64 format so that it can be sent as a regular mail attachment
  • -in to specify the file to be encrypted
  • -out to specify the name of the encrypted file output
  • -pass to give the password
  • -p if you want to output the ‘salt’ and key used, which we will ‘pipe’ into a file to keep.

So a complete command line might read
openssl aes-256-cbc -e -salt -S FFFFFFFFFFFFFFFF -a -in test.pdf -out test.base64 -pass pass:"quadrupedante" -p > test.pwd
to encrypt saving the salt and key in the file test.pwd, and
openssl aes-256-cbc -d -a -in test.base64 -out test.pdf -pass pass:"quadrupedante"
to decrypt.

Could someone break into such an encrypted file without knowing the password (provided that is robust and unguessable)? I very much doubt it.