Encrypting backups using age and the value of simplicity
A little obvious
Backups must be stored (better – stored in multiple copies, including, of course, somewhere outside) and they must be encrypted. Everyone seems to agree with this, but in reality, few people do it. This means that people are divided into those who do not yet encrypt backups (they have not yet been able to realistically imagine and feel the possible risks) and responsible, experienced people whose dickpics have been seen by the entire Internet (whom we know, figuratively speaking, by sight). Now that we have, in some ways, known each other for a long time, let us move on to the article.
Crypto Disclaimer
The author is not a cryptographer, and does not even pretend to be that title. And the topic of encryption is a complex one, and without understanding it is easy to do something that at first glance seems secure (for example, quite well encrypted), but in fact is almost open.
For those who don’t know, I recommend spending 2-3 minutes and familiarizing yourself a little ECB-penguin.
I crashed like this once (fortunately, I found the mistake myself). I chose the mode of gluing ECB blocks (they are different there: ECB, CBC, CTR, GCM, XTS) – I logically decided that the cryptographic strength may be different, but there will be no crap in openssl. And I was wrong. Cryptography and popular standard crypto tools allow you to shoot yourself in the foot, allowing you to be fooled into a false sense of security.
However, I didn’t immediately find a good guide for the task I needed (I’m sure there are some, but I didn’t come across them), so let there be one more.
What is age and can you trust it?
age (pronounced not “age”, but conveniently, in Russian, “age”, with “g” as in “gif”) is a new, popular encryption tool (17k stars stars on github). age uses a bunch of ChaCha20 algorithms for symmetric encryption with the Message authentication code (MAC) algorithm Poly1305 (RFC7539) by DJ Bernstein. The same one that ed25519 invented, which you (hopefully) use in ssh keys. By the way, this ed25519 is also used in wireguard and age too.
You can simply install via apt install age
.
Author – utilities (can you trust it?) Filippo Valsorda worked in the Cloudflare crypto team, heads the Go security team at Google.
We just use it!
First – the simplest encryption, just a password, for the little ones.
# encrypt
$ age -p -o paris.jpg.age paris.jpg
Enter passphrase (leave empty to autogenerate a secure one):
Confirm passphrase:
# decrypt
$ age -d -o paris-decrypted.jpg paris.jpg.age
Enter passphrase:
This is already enough to store files somewhere on a Yandex.disk and not be afraid that Yandex, a hacker or intelligence agencies will read them.
But let's look at a more interesting option, which is no longer a shame to use in production. We want to encrypt database backups before uploading them to S3. There are several difficulties here:
We don't want to store any private or symmetric keys on the server.
Several people in the company (“recipients”) should be able to decrypt the backups. So that even if one leaves the team, someone else can decrypt the backup.
We don't want to use one “super key” and give it to everyone. As a rule, such a key quickly leaks (through hacked instant messengers, correspondence) and the worst thing is that we cannot even find out from whom it leaked. Each recipient must be able to decrypt with his own individual key, which he does not share anywhere.
First, a little theory of how it works. Asymmetric encryption is not suitable for encrypting large amounts of data. Therefore, a random encryption key is generated, the file itself is symmetrically encrypted with the ChaCha20 algorithm using this key, and then this key, encrypted with the public key of each recipient, is added several times to the output file.
Where can I get the keys? The first option is to generate them: age-keygen -o key.txt
will create a pair of public and private keys ed25519. But… why? Nowadays, everyone has an SSH key in the ed25519 format or, at worst, RSA. Let's not multiply existing keys and let's use them, age can do it! Recipients can be added to the encrypted file by repeating the argument -r KEY
(we pass the value of the public key directly as an argument), or R file
– where the file lists (one or more) public keys. Your ~/.ssh/id_ed25519.pub
quite suitable as an encryption key. But we will write all recipients in one file recipients.txt
:
# john doe
ssh-ed25519 AAAA....
# my key
ssh-ed25519 AAAA....
Yes, empty lines and hash marks are possible. and even ~/.ssh/authorized_keys
quite suitable as such a file.
Well, let's go:
$ age -o paris.jpg.age -R recipients.txt paris.jpg
Received paris.jpg.age
the file can be freely uploaded to your favorite file hostingeven in S3, even in Dropbox, even in Skype.
If we suddenly decide to recover and want to decipher:
$ age -d -o paris.jpg -i ~/.ssh/id_ed25519 paris.jpg.age
As you can see, everything is simple, and most importantly, there are no extra incomprehensible buttons and twists that could be pressed incorrectly.
Why I like age (holivar a little)
Firstly – age, it is simple, cheap and quick to implement. As Boris Razor said about cryptography: simplicity is good, simplicity is reliable! From a practical point of view, age is a tool about which you just read an article, after 15 minutes you played around and saw that it works, and by the evening you started encrypting backups efficiently and reliably. This works. Some complex schemes – there is a high probability that while you understand them at a sufficient level, other important matters, tasks will arise, you will switch and simply not do any encryption. Therefore, I am a supporter of simple and reliable solutions.
Second, the simplicity of age also has advantages from the cryptographic side. Most likely, the algorithms chosen by the author are good enough for this (quite typical for everyone) task, in which you do not need to select special algorithms “according to your unique needs.” I think the competent author of the utility made a better choice of algorithms than I would have done (with my crypto literacy, as in the illustration above).
The third plus is that age simply does not have unnecessary twists or options that you would not need. There is no risk that if you use age incorrectly, you will shoot yourself in the foot and end up with backups that someone will hack on your home computer in an hour.
I haven't actively used PGP/GPG other than to play around, but I have used openssl. The experience was so painful and traumatic that my psychological trauma from using openssl to work with X.509 certificates was sublimated into the project showcert (article on Habré about showcert), 70+ stars on Github. All typical operations with certificates, from viewing a certificate from a file or on a remote server to creating your own CA, are done with simple, short, intuitive commands. Compare:
# you will never forget how to read certificate with showcert
showcert habr.com
# two redirections, pipe, two invocations and 5 unneeded options
openssl s_client -connect habr.com:443 /dev/null | openssl x509 -inform pem -text
I've been using openssl for many years to verify certificates and never I couldn’t print this pipeline of two commands from memory without errors – I always started with Google to find it. Compare with the first team, where it is impossible to make a mistake, there is simply nowhere. Therefore, to me, age looks like a reasonable simplification.
openssl left me with the impression not of a tool for solving a problem, but rather of a spacer, a CLI interface to a very rich zoo of various cryptographic functions (of which 99% you don’t need, and the remaining 1% you don’t understand how to use, when GCM is better than XTS , but you can google it and copy the spell from the browser into the shell).
Below, in the “links for holivar” there is a good illustration (stackoverflow) where a long “spell” with openssl actually encrypts a file. This answer is downvoted, many thousands of people copy and use it, and only below in the comments to the answer is it written why it is wrong to do this. The same ECB penguin effect from the beginning of the article. People make cryptography based on a semi-literate comment from who knows who, plused by even more cryptography illiterate people.
But age is precisely an encryption utility, a tool for a specific purpose. It doesn’t pretend to be a Swiss army knife that can even repair a starship, but it cuts cervelat perfectly.
Also, I really liked the argument from @stargrave2’s article on the Libre/OpenPGP vs OpenSSH/age hub:
When was the last time we saw a format or protocol being broken because it contained a vulnerable cipher? RC4, which was never seriously used anywhere if cryptographers were involved? But if in a protocol or format it is possible to coordinate/select these algorithms, then we have seen a lot of downgrade attacks or vulnerabilities in ASN.1 parsers (due to the forcedly complex formats). Mono-algorithm solutions are simply not susceptible to these attacks.
Read on the topic and for holivars age/pgp/openssl
Stackoverflow pages are worth reading with comments