A while back I learned about age, which describes itself as “A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.” As someone who’s struggled to learn and use PGP, I was intrigued!
Should I use age or rage?
There’s a implementation of age written in Rust called rage, which is inter-operable with age (the original golang version). Since I write some Rust, I chose to learn using rage, so all the commands below use
rage. But given how rage and age are inter-operable, and I think the commands are the same, you could install age and still follow this post – just be sure to use
age wherever you see
Note that, as of this writing, age encrypts large files about twice as fast as rage.
Since I have an up-to-date version of the Rust language installed (1.46) already set up, I installed rage by running
cargo install rage.
Using rage to encrypt a file with a passphrase
Let’s say we have a file called secrets.txt that we want to encrypt, such that only someone who knows a certain passphrase can decrypt it. We could just run:
$ rage -p -o secrets_encrypted.txt secrets.txt
Your terminal with then prompt you to enter your chosen the passphrase (if you don’t provide one, rage will generate a nice long one for you). I left the passphrase field blank so that rage would generate a passphrase for me. Here’s what I got:
$ rage -p -o secrets_encrypted.txt secrets.txt Using an autogenerated passphrase: skull-tribe-mirror-help-logic-maple-syrup-round-click-danger
Rage created a new file called “secrets_encrypted.txt” that is encrypted and thus unreadable. The original secrets.txt is still in tact.
Decrypting file with a passphrase
Decrypting this file is simple. Just run
$ rage -d -o secrets_decrypted.txt secrets_encrypted.txt
Running this command prompts you to enter the passphrase we set when encrypting the file. If you enter the passphrase correctly, rage decrypts the file into a new file called secrets_decrypted.txt. Again, the original “secrets_encrypted.txt” file is left in tact.
Using a public/private key-pair
Encrypting and decrypting files with secret passphrases can be useful, but one downside is that you have to securely get that passphrase to the other party. We can avoid this issue by using a public/private key-pair, which rage also supports.
When we installed rage, we got two executables:
rage, which we’ve been using, and
rage-keygen, which we haven’t used yet. rage-kleygen generate key-pairs for us. Let’s make a key-pair now.
$ rage-keygen > test_key.txt
Running this command will print our new public key.
Public key: age1s366ey709nfd29jpaapvq2s2w29wjv9y68v9vvz5rc5v3tgge4xq7afnej
It also places both this public key and our private or secret key in a file called test_key.txt. You should not share your secret key with anyone. But since this is a demonstration, I’ll copy and paste the contents of my new test_key.txt file below.
# created: 2020-09-08T15:39:39-04:00 # public key: age1s366ey709nfd29jpaapvq2s2w29wjv9y68v9vvz5rc5v3tgge4xq7afnej AGE-SECRET-KEY-1URL6WQVKQ0ULFDH7S0UL3ZFL2FU0WAKD778CLK5E9ASH40S8R90QE8E20V
As you can see, the file contains both our public key and our secret key (don’t share it with anyone!).
Encrypting a file for a public key
Let’s say someone else wants to encrypt a file for us, the holder of the key above. Let’s say the file they want to encrypt for us is file_for_keyholder_only.txt. They’d run
$ rage -o file_for_keyholder_only_encrypted.txt -r age1s366ey709nfd29jpaapvq2s2w29wjv9y68v9vvz5rc5v3tgge4xq7afnej file_for_keyholder_only.txt
That’s a long one, so let’s go over it. As above with the passphrase example, the
-o flag tells rage where we’d like to place the output of this command – in this case, a new file that will be encrypted. Next is the
-r flag, which stands for recipient. Here, we’re telling rage that we want to encrypt this file for a particular recipient, namely the owner of this specific public key (remember, public keys can be shared safely out in the open). Then, lastly, we tell rage which file we want to act on, in this case “file_for_keyholder_only.txt”, the file we wish to encrypt.
Once we hit enter, rage creates a new, encrypted file called file_for_keyholder_only_encrypted.txt.
Decrypting a file with a secret key
Now let’s say we receive a file that’s been encrypted for us using our public key. We want to decrypt it. We’ll run:
$ rage -o decrypted.txt -i test_key.txt -d file_for_keyholder_only_encrypted.txt
Which will decrypt the file to “decrypted.txt”. Note the
-i flag pointing to the key-pair file (which contains the secret key), and the
-d flag for decryption, which we’re already familiar with.
Creating a more permanent identity
If you want to create a key-pair that you’ll use more permanently, the age documentation recommends storing the key file in
~/.config/age/keys.txt. You’d do this by running
$ mkdir -p ~/.config/age $ rage-keygen >> ~/.config/age/keys.txt
This is also handy because rage will look to that location first for key-pairs when decrypting. This means you can just run
rage -d encrypted_file.txt (without specifying a key-pair file with
-i like we did above), and rage will use the key-pair located at
~/.config/age/keys.txt as a default.
As before, you can share this public key broadly and publicly, so that others could encrypt files for you. For example, I now have a public age/rage key in a Github Gist that I link to from some of my social media accounts. Just remember: Don’t share your secret key!
Can you encrypt/decrypt text rather than a file?
What if you just want to encrypt a line or two of text, rather than a file? You can “pipe” in an echo command (note that rage requires that you encrypt using a public key, rather than a passphrase):
$ echo "secret message from echo" | rage -a -r age180d9ut0ff3zzkq6umq588p7zlqqetuf8nhxxfhsysmg4hjyt55lsjraysp
which prints the encrypted text to the terminal:
-----BEGIN AGE ENCRYPTED FILE----- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvUWtNRmhYbURWQTRYL2ZF Z2h2ZWhLdVc1S1RWZWRIV293UkZ1RWMxb2tjCkxxcStGMzhWODdzN0RBNDlTMmlM ZXczeTNydzAyMkVleTF4MUd0QnpheEkKLT4gam9pbnQtb2lsLWMwIksuICgKWjQ5 OEgxU2hiNE9CTjhCdjlkeURuRFU1RWl5TEMwREh0VzRKUm1JT2ZBU1hKUVZOeXVM emFyNHZSbGp1eTdYUgp4N29xbUtYdnZSREQyL2NtdXMzcTVBbEN5VGVUT0lrVERt SGR3UjVCMmZZT1VZOAotLS0gREVxbjZ3Q0s4cnBSL0ZPZ3g3RVpWTUtLMk0zWU5C NVgrNmRsbG9ybDJoawqvEbV6F/m6uYjcD7mBmfFiUMaRX/y/nzNlal+zaO9yBVPV xvRY+zVyXtYPtvAz42vGrMdGeeGD0+8= -----END AGE ENCRYPTED FILE-----
-a flag stands for “armor” and it tells rage to encrypt to a PEM encoded format, which is easier to copy and paste and move around in general.
Having this block of text printed to the terminal screen isn’t super helpful. We already know how to print it to a file, using the
-o flag. But this time, how about we pipe it directly to the clipboard? If you’re using Linux and have
xsel installed, you’d do this:
echo "secret message from echo" | rage -a -r age180d9ut0ff3zzkq6umq588p7zlqqetuf8nhxxfhsysmg4hjyt55lsjraysp | xsel --clipboard
(On Mac, try
| pbcopy at the end, though I haven’t tested this. Other systems may have yet another tools called xclip installed.)
To decrypt an encrypted message currently in your clipboard, you’d run:
xsel --clipboard | rage -d
which will print the decrypted message to the terminal screen.
This guide is by no means exhaustive of what you can already do with these tools. Both rage and age currently have more features than I’ve outlined here. Check them out in each of their documentation!