Encrypt files with age

Encrypt files with age: generate a key, encrypt to one or more recipients or SSH keys, use a passphrase, and encrypt whole directories through tar.

how-to8 steps

Updated

in short

Generate a key with age-keygen -o key.txt, encrypt with age -r <public key>, and decrypt with age -d -i key.txt. Use -p when you want a passphrase instead of a key.

age encrypts a file to one or more public keys (recipients) and decrypts it with the matching private key (identity). Keys are short strings, there is no keyring and no config file, and it reads from standard input and writes to standard output, so it fits into pipes.

This guide covers keys, passphrases, SSH keys, recipient files, text-safe output and encrypting a directory with tar.

Tools used

Before you start

  • macOS, Linux, BSD or Windows
  • For the SSH key steps: an ssh-ed25519 or ssh-rsa key pair

Steps

  1. Step 1: Install age

    age is packaged for most systems. Debian 12+, Ubuntu 22.04+ and Fedora carry it in the default repositories. The package installs both age and age-keygen.

    sh
    # macOS or Linux with Homebrew
    brew install age
    
    # Debian 12+ / Ubuntu 22.04+
    sudo apt install age
    
    # Fedora
    sudo dnf install age
    
    # Arch Linux
    sudo pacman -S age
    
    # Windows
    winget install --id FiloSottile.age
    sh
    age --version
  2. Step 2: Generate a key pair

    age-keygen -o writes the private key to a new file with 0600 permissions and prints the public key. It refuses to overwrite an existing file. The public key starts with age1 and is safe to share; the file holds the secret key, which starts with AGE-SECRET-KEY-1.

    age-keygen -y prints the public key again from the key file.

    sh
    mkdir -p ~/.config/age
    age-keygen -o ~/.config/age/key.txt
    output
    Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
    sh
    age-keygen -y ~/.config/age/key.txt
  3. Step 3: Encrypt and decrypt with a key

    -r takes a public key and can be repeated; every listed recipient can decrypt the file on their own. -o sets the output file; without it age writes to standard output. To decrypt, pass -d and the key file with -i.

    sh
    age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p -o notes.txt.age notes.txt
    sh
    # two recipients
    age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p \
        -r age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg \
        -o notes.txt.age notes.txt
    sh
    age -d -i ~/.config/age/key.txt -o notes.txt notes.txt.age
  4. Step 4: Use a recipients file

    With more than one or two recipients, list the public keys in a file, one per line, and pass it with -R. Empty lines and lines starting with # are ignored. -R can be repeated and combined with -r.

    sh
    cat > recipients.txt <<'EOF'
    # Alice
    age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
    # Bob
    age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg
    EOF
    
    age -R recipients.txt -o notes.txt.age notes.txt
  5. Step 5: Encrypt to SSH keys

    age accepts ssh-ed25519 and ssh-rsa public keys as recipients and the matching private key file as the identity. Keys held in ssh-agent or on hardware tokens are not supported. An SSH public key file works with -R, and so does a GitHub .keys URL piped in with -R - (the input file must then be given as an argument).

    Files encrypted to an SSH key carry a tag that links them to that public key.

    sh
    age -R ~/.ssh/id_ed25519.pub -o notes.txt.age notes.txt
    age -d -i ~/.ssh/id_ed25519 -o notes.txt notes.txt.age
    sh
    # encrypt to the SSH keys on a GitHub profile
    curl -s https://github.com/<user>.keys | age -R - -o notes.txt.age notes.txt
  6. Step 6: Encrypt with a passphrase

    -p asks for a passphrase on the terminal and offers to generate one if you leave it empty. It cannot be combined with -r, -R or -i. Decryption detects passphrase files on its own, so run age -d without -i.

    sh
    age -p -o secrets.txt.age secrets.txt
    output
    Enter passphrase (leave empty to autogenerate a secure one):
    sh
    age -d -o secrets.txt secrets.txt.age
    output
    Enter passphrase:
  7. Step 7: Produce text-safe output with -a

    Encrypted files are binary. -a (--armor) writes a PEM-style text block instead, for pasting into an email, chat or a YAML file. Decryption detects armor automatically.

    sh
    age -a -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p notes.txt
    output
    -----BEGIN AGE ENCRYPTED FILE-----
    ...
    -----END AGE ENCRYPTED FILE-----
  8. Step 8: Encrypt a directory with tar

    age encrypts a single stream, so archive a directory with tar first. Both directions work in a pipe without writing the unencrypted archive to disk.

    sh
    tar czf - ~/documents | age -R recipients.txt > documents.tar.gz.age
    sh
    age -d -i ~/.config/age/key.txt documents.tar.gz.age | tar xzf -

Troubleshooting

  • refusing to output binary to the terminal: add -o file, redirect with >, or use -a.
  • no identity matched any of the recipients: the file was not encrypted to the key you passed with -i.
  • file is passphrase-encrypted but identities were specified: drop -i and run age -d alone.
  • -p/--passphrase can't be combined with -r/--recipient: use either a passphrase or recipients, not both.
  • SSH key in ssh-agent or on a YubiKey: age cannot use it. Pass a private key file, or use a native age key.

Tips

  • age 1.3.0+ supports post-quantum keys: age-keygen -pq. Their public keys are about 2000 characters long.
  • A key file can itself be passphrase-protected: age-keygen | age -p > key.age, then decrypt with -i key.age.
  • age 1.3.0+ ships age-inspect, which shows the recipient types and sizes of an encrypted file without decrypting it.

FAQ

Should I use a key or a passphrase?
Use a key for anything a script or another person decrypts; it needs no prompt and supports multiple recipients. Use a passphrase for a one-off file you will decrypt yourself.
Can I add a recipient to a file that is already encrypted?
No. The recipient list is fixed at encryption time. Decrypt the file and encrypt it again with the new recipient list.
Can I encrypt a file to myself without the public key?
Yes. With `-e` set explicitly, `-i` encrypts to the identity in the key file: `age -e -i key.txt file.txt > file.txt.age`.

related