Sept 2021 Update: With the release of age v1.0, I’ve written a brand-new how-to post. The syntax below may be outdated now.

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!

There’s more info in this public Google Doc. Note: age is currently in beta.

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 rage.

Note that, as of this writing, age encrypts large files about twice as fast as rage.

Installation

To install rage, there are a couple options listed in the README on Github, including homebrew, (likewise with age, if you’re going that route).

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

You can then use --identity ~/.config/age/keys.txt to use your saved key.

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-----

The -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 other tools for this – another popular one is called xclip.)

To decrypt an encrypted message currently in your clipboard with your stored key, you could run:

xsel --clipboard | rage -d -i ~/.config/age/keys.txt

which should print the decrypted message to the terminal screen.

More features

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!

To look forward to

It looks like the developer(s) of rage seem to be working on (and discussing) some sort of Yubikey plugin, though I’m not sure of its current status. That’d be pretty cool though!