Poor Man’s Encryption

Table of Contents

Dear user: This article has moved to a new location. Please update your bookmarks.

1. Introduction

Suppose you need to send a file with sensitive information to another person. The obvious answer is to encrypt the file. So, you ask for the recipient’s PGP key only to be met with, “What’s PGP? Is it a psychoactive drug?”

Now, you need to make compromises and agree on a common tool. Good luck!

It’s 2020. How hard can it be to find a common tool for encryption? If you read this guide, then it’s easier than you might think. This guide documents some ways that work effectively and some common traps to avoid. It is written for a Linux user who wishes to send sensitive data to another user who most likely isn’t running Linux.

2. Revision History

Version Date Comment
1.0 [2020-10-10 Sat] 3 tricks: PGP, ZIP, and PDF

3. Transfer mechanisms

When sending a file, consider how the transfer mechanism works. Some transfer mechanisms are more secure than others. A good mechanism meets the CIA triad.

Confidentiality
The file is disclosed to the recipient and no one else.
Integrity
The file is not modified in transit.
Availability
The receiver can actually view the file when he tries to open it.

Now, this is the poor man’s guide encrypting a file. If you consider yourself a cryptonut, then please stop reading. Now! Seriously! You aren’t going to like this guide because by now you are a proud adopter of a method you like, and your pride is going to urge you snub at me and this guide.

Are you still reading? Good! Now I can be serious. The priority of this guide is availability, because both you and the recipient must agree on a common tool. Confidentiality comes in a close second. The reason is because a super-confidential mechanism is useless if the recipient cannot decode your message.

Integrity comes last because you can utilize a side channel to verify file integrity.

3.1. Importance of a “side channel”

In a secure file transfer scenario, it is a very good idea to have a side channel for communication. A side channel is a second communication mechanism other than the one which is used to transfer the data. Side channels can be used for sending a password (used for decryption) and verifying someone’s key. In an extreme scenario, the side channel might be an in-person meeting.

3.2. Plain text, client-server, and end-to-end

Some mechanisms, such as email and SMS, send data in plain text. Please be aware of this, and definitely encrypt sensitive data when using these channels. RFC 1855 recommends, “never put in a mail message anything you would not put on a postcard.” Anyone in the transport chain can read it!

Some mechanisms, including most modern Internet-based messaging systems and storage providers, use client-server encryption. This means that data is encrypted in transit, but is not encrypted on the server. In some cases, the data may be encrypted on the server, but the operators have the key to decrypt the data, in which case the at-rest encryption doesn’t help you much.

Some mechanisms encrypt data in a true end-to-end manner (also called client-client encryption). When implemented properly, end-to-end encryption makes it computationally infeasible for a middleman to decrypt the message. Example systems that use true end-to-end encryption are Pretty Good Privacy (PGP), Telegram secret chats, and Matrix (now called Element.io).

4. Tools

4.1. Pretty Good Privacy (PGP)

Pretty Good Privacy (PGP) is an ideal solution. The modern GnuPG implementation is powerful and can be used as an additional layer of security on top of a plaintext communication channel.

The one problem is that very few people outside the Linux community use PGP. Even inside the Linux community, use of PGP has waned dismally.

If you wish to use PGP, you and the recipient will each need to generate a PGP key (outside of the scope of this document) and then verify each other’s keys over a side channel, traditionally in an in-person “key signing party” (also outside the scope of this document).

Once you have each other’s public keys, the rest of the job is easy.

To encrypt a file, use the --encrypt flag.

$ gpg --encrypt -r <id> sensitive.txt

To encrypt several files, use --encrypt-files.

$ gpg --encrypt-files -r <id> sensitive1.txt sensitive2.txt ...

To encrypt a message in STDIN, use --encrypt and omit the file name. In this manner, GnuPG can be run in a pipeline.

$ gpg --encrypt -r <id>

Once your file is encrypted, send it over the channel of your choice.

A useful flag that can be added to encrypt operations is -a, which formats the result in an ASCIIfied way. When the ciphertext is in ASCII, you can send it over any text-only channel. In this way, you can encrypt an image and send it over e.g. SMS on a phone carrier.

To decrypt one or more files, use --decrypt-files. GnuPG will ask you for the password of your key.

$ gpg --decrypt-files sensitive.txt.gpg

To decrypt from STDIN, simply use --decrypt. In this manner, GnuPG can be run in a pipeline.

$ gpg --decrypt

4.2. ZIP with password protection

ZIP has a handy lesser-known feature: encrypting a file with a passphrase. Also, every modern operating system comes with a ZIP implementation, making ZIP password protection highly available.

However, be warned that the default ZipCrypto algorithm is considered weak by today’s standards. To make matters more complicated, the ZIP tools bundled with modern operating systems (Windows Explorer, macOS Finder, and Linux’s Info-ZIP) only support ZipCrypto. Any attempt to decrypt something other than ZipCrypto will yield an error message. So, there is a trade-off between confidentiality and availability.

If you want better encryption, then use AES. 7-Zip supports AES, and it is cross-platform. On Windows, WinZip supports AES. On Linux, you can use either 7-Zip or BSD’s tar implementation (packaged as bsdtar in most distributions).

bsdtar is command line based, and it is usually installed on modern Linux distributions by default. To encrypt a file using bsdtar on Linux:

$ bsdtar -a -cf sensitive.zip --options zip:encryption=aes256 sensitive.txt

You can replace aes256 with aes128, or you can fall back to zipcrypt for traditional (weak) ZipCrypto.

The command will prompt you for a password. Send the password to the recipient via a side channel.

4.3. PDF encryption

PDF also has a feature to encrypt documents. This feature is somewhat entangled with the poorly designed “permissions” system of yesteryear (e.g. permission to print, etc). However, when configured properly, the entire document is encrypted. Furthermore, PDF 1.6 uses AES-128, and PDF 1.7 uses AES-256 (according to Adobe). So, the encryption is pretty good, and documents can be decrypted by any PDF reader.

On Linux, you can encrypt a PDF with Ghostscript.

$ gs -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -sOwnerPassword=balloons -sUserPassword=balloons -sOutputFile=sensitive.pdf sensitive-enc.pdf

(Of course, you probably want to pick a better password than ‘balloons’. Also, send the password to the recipient via a side channel.)

As of ghostscript 9.26, this command outputs a PDF 1.7 document, so AES-256 is used.

Make sure you set both the owner password and the user password to the same string. The dichotomy is an artifact from the era of bad PDF protection. What is important now is that both values are set and equal.

Once you are happy with the encryption, safely destruct the plaintext copy by writing random data to it.

$ shred sensitive.pdf
$ mv sensitive-enc.pdf sensitive.pdf

5. Conclusion

There you have it! This is the “poor man’s guide” to encryption. These are a few ways to send a file securely such that users on other operating systems can decrypt the file.

6. Contact Me

Questions? Comments? If you have a clever encryption trick stronger than an Ovaltine decoder ring, I would love to hear about it. Contact me.