age
- simple, modern, and secure file encryption
age
[--encrypt
] (-r
RECIPIENT | -R
PATH)... [--armor
] [-o
OUTPUT] [INPUT]
age
[--encrypt
] --passphrase
[--armor
] [-o
OUTPUT] [INPUT]
age
--decrypt
[-i
PATH | -j
PLUGIN]... [-o
OUTPUT] [INPUT]
age
encrypts or decrypts INPUT to OUTPUT. The INPUT argument is
optional and defaults to standard input. Only a single INPUT file may be
specified. If -o
is not specified, OUTPUT defaults to standard output.
If -p
/--passphrase
is specified, the file is encrypted with a passphrase
requested interactively. Otherwise, it's encrypted to one or more
RECIPIENTS specified with -r
/--recipient
or
-R
/--recipients-file
. Every recipient can decrypt the file.
In -d
/--decrypt
mode, passphrase-encrypted files are detected automatically
and the passphrase is requested interactively. Otherwise, one or more
IDENTITIES specified with -i
/--identity
are
used to decrypt the file.
age
encrypted files are binary and not malleable, with around 200 bytes of
overhead per recipient, plus 16 bytes every 64KiB of plaintext.
-o
, --output
=OUTPUTWrite encrypted or decrypted file to OUTPUT instead of standard output. If OUTPUT already exists it will be overwritten.
If encrypting without --armor
, age
will refuse to output binary to a
TTY. This can be forced by specifying -
as OUTPUT.
--version
Print the version and exit.
-e
, --encrypt
Encrypt INPUT to OUTPUT. This is the default.
-r
, --recipient
=RECIPIENTEncrypt to the explicitly specified RECIPIENT. See the RECIPIENTS AND IDENTITIES section for possible recipient formats.
This option can be repeated and combined with other recipient flags, and the file can be decrypted by all provided recipients independently.
-R
, --recipients-file
=PATH Encrypt to the RECIPIENTS listed in the
file at PATH, one per line. Empty lines and lines starting with #
are ignored as comments.
If PATH is -
, the recipients are read from standard input. In
this case, the INPUT argument must be specified.
This option can be repeated and combined with other recipient flags, and the file can be decrypted by all provided recipients independently.
-p
, --passphrase
Encrypt with a passphrase, requested interactively from the terminal.
age
will offer to auto-generate a secure passphrase.
This option can't be used with other recipient flags.
-a
, --armor
Encrypt to an ASCII-only "armored" encoding.
age
armor is a strict version of PEM with type AGE ENCRYPTED FILE
,
canonical "strict" Base64, no headers, and no support for leading and
trailing extra data.
Decryption transparently detects and decodes ASCII armoring.
-i
, --identity
=PATH Encrypt to the RECIPIENTS corresponding to the
IDENTITIES listed in the file at PATH. This
is equivalent to converting the file at PATH to a recipients file with
age-keygen -y
and then passing that to -R
/--recipients-file
.
For the format of PATH, see the definition of -i
/--identity
in the
Decryption options section.
-e
/--encrypt
must be explicitly specified when using -i
/--identity
in encryption mode to avoid confusion.
-j
PLUGINEncrypt using the data-less plugin PLUGIN.
This is equivalent to using -i
/--identity
with a file that contains a
single plugin IDENTITY
that encodes no plugin-specific data.
-e
/--encrypt
must be explicitly specified when using -j
in encryption
mode to avoid confusion.
-d
, --decrypt
Decrypt INPUT to OUTPUT.
If INPUT is passphrase encrypted, it will be automatically detected
and the passphrase will be requested interactively. Otherwise, the
IDENTITIES specified with -i
/--identity
are used.
ASCII armoring is transparently detected and decoded.
-i
, --identity
=PATHDecrypt using the IDENTITIES at PATH.
PATH may be one of the following:
a. A file listing IDENTITIES one per line.
Empty lines and lines starting with "#
" are ignored as comments.
b. A passphrase encrypted age file, containing IDENTITIES one per line like above. The passphrase is requested interactively. Note that passphrase-protected identity files are not necessary for most use cases, where access to the encrypted identity file implies access to the whole system.
c. An SSH private key file, in PKCS#1, PKCS#8, or OpenSSH format. If the private key is password-protected, the password is requested interactively only if the SSH identity matches the file. See the SSH keys section for more information, including supported key types.
d. "-
", causing one of the options above to be read from standard input.
In this case, the INPUT argument must be specified.
This option can be repeated. Identities are tried in the order in which are
provided, and the first one matching one of the file's recipients is used.
Unused identities are ignored, but it is an error if the INPUT file is
passphrase-encrypted and -i
/--identity
is specified.
-j
PLUGINDecrypt using the data-less plugin PLUGIN.
This is equivalent to using -i
/--identity
with a file that contains a
single plugin IDENTITY
that encodes no plugin-specific data.
RECIPIENTS
are public values, like a public key, that a file can be encrypted
to. IDENTITIES
are private values, like a private key, that allow decrypting
a file encrypted to the corresponding RECIPIENT
.
Native age
key pairs are generated with age-keygen(1), and provide small
encodings and strong encryption based on X25519. They are the recommended
recipient type for most applications.
A RECIPIENT
encoding begins with age1
and looks like the following:
age1gde3ncmahlqd9gg50tanl99r960llztrhfapnmx853s4tjum03uqfssgdh
An IDENTITY
encoding begins with AGE-SECRET-KEY-1
and looks like the
following:
AGE-SECRET-KEY-1KTYK6RVLN5TAPE7VF6FQQSKZ9HWWCDSKUGXXNUQDWZ7XXT5YK5LSF3UTKQ
An encrypted file can't be linked to the native recipient it's encrypted to without access to the corresponding identity.
As a convenience feature, age
also supports encrypting to RSA or Ed25519
ssh(1) keys. RSA keys must be at least 2048 bits. This feature employs more
complex cryptography, and should only be used when a native key is not available
for the recipient. Note that SSH keys might not be protected long-term by the
recipient, since they are revokable when used only for authentication.
A RECIPIENT
encoding is an SSH public key in authorized_keys
format
(see the AUTHORIZED_KEYS FILE FORMAT
section of sshd(8)), starting with
ssh-rsa
or ssh-ed25519
, like the following:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDULTit0KUehbi[...]GU4BtElAbzh8=
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH9pO5pz22JZEas[...]l1uZc31FGYMXa
The comment at the end of the line, if present, is ignored.
In recipient files passed to -R
/--recipients-file
, unsupported but valid
SSH public keys are ignored with a warning, to facilitate using
authorized_keys
or GitHub .keys
files. (See EXAMPLES.)
An IDENTITY
is an SSH private key file passed individually to
-i
/--identity
. Note that keys held on hardware tokens such as YubiKeys
or accessed via ssh-agent(1) are not supported.
An encrypted file can be linked to the SSH public key it was encrypted to.
This is so that age
can identify the correct SSH private key before
requesting its password, if any.
age
can be extended through plugins. A plugin is only loaded if a corresponding
RECIPIENT
or IDENTITY
is specified. (Simply decrypting a file encrypted with
a plugin will not cause it to load, for security reasons among others.)
A RECIPIENT
for a plugin named example
starts with age1example1
, while an
IDENTITY
starts with AGE-PLUGIN-EXAMPLE-1
. They both encode arbitrary
plugin-specific data, and are generated by the plugin.
When either is specified, age
searches for age-plugin-example
in the PATH
and executes it to perform the file header encryption or decryption. The plugin
may request input from the user through age
to complete the operation.
Plugins can be freely mixed with other plugins or natively supported keys.
A plugin is not bound to only encrypt or decrypt files meant for or generated by
the plugin. For example, a plugin can be used to decrypt files encrypted to a
native X25519 RECIPIENT
or even with a passphrase. Similarly, a plugin can
encrypt a file such that it can be decrypted without the use of any plugin.
Plugins for which the IDENTITY
/RECIPIENT
distinction doesn't make sense
(such as a symmetric encryption plugin) may generate only an IDENTITY
and
instruct the user to perform encryption with the -e
/--encrypt
and
-i
/--identity
flags. Plugins for which the concept of separate identities
doesn't make sense (such as a password-encryption plugin) may instruct the user
to use the -j
flag.
age
will exit 0 if and only if encryption or decryption are successful for the
full length of the input.
If an error occurs during decryption, partial output might still be generated, but only if it was possible to securely authenticate it. No unauthenticated output is ever released.
Files encrypted with a stable version (not alpha, beta, or release candidate) of
age
, or with any v1.0.0 beta or release candidate, will decrypt with any later
version of the tool.
If decrypting older files poses a security risk, doing so might cause an error by default. In this case, a flag will be provided to force the operation.
Generate a new identity, encrypt data, and decrypt:
$ age-keygen -o key.txt
Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
$ tar cvz ~/data | age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p > data.tar.gz.age
$ age -d -o data.tar.gz -i key.txt data.tar.gz.age
Encrypt example.jpg
to multiple recipients and output to example.jpg.age
:
$ age -o example.jpg.age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p \
-r age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg example.jpg
Encrypt to a list of recipients:
$ cat > recipients.txt
# Alice
age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
# Bob
age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg
$ age -R recipients.txt example.jpg > example.jpg.age
Encrypt and decrypt a file using a passphrase:
$ age -p secrets.txt > secrets.txt.age
Enter passphrase (leave empty to autogenerate a secure one):
Using the autogenerated passphrase "release-response-step-brand-wrap-ankle-pair-unusual-sword-train".
$ age -d secrets.txt.age > secrets.txt
Enter passphrase:
Encrypt and decrypt with a passphrase-protected identity file:
$ age-keygen | age -p > key.age
Public key: age1yhm4gctwfmrpz87tdslm550wrx6m79y9f2hdzt0lndjnehwj0ukqrjpyx5
Enter passphrase (leave empty to autogenerate a secure one):
Using the autogenerated passphrase "hip-roast-boring-snake-mention-east-wasp-honey-input-actress".
$ age -r age1yhm4gctwfmrpz87tdslm550wrx6m79y9f2hdzt0lndjnehwj0ukqrjpyx5 secrets.txt > secrets.txt.age
$ age -d -i key.age secrets.txt.age > secrets.txt
Enter passphrase for identity file "key.age":
Encrypt and decrypt with an SSH public key:
$ age -R ~/.ssh/id_ed25519.pub example.jpg > example.jpg.age
$ age -d -i ~/.ssh/id_ed25519 example.jpg.age > example.jpg
Encrypt and decrypt with age-plugin-yubikey:
$ age-plugin-yubikey # run interactive setup, generate identity file and obtain recipient
$ age -r age1yubikey1qwt50d05nh5vutpdzmlg5wn80xq5negm4uj9ghv0snvdd3yysf5yw3rhl3t secrets.txt > secrets.txt.age
$ age -d -i age-yubikey-identity-388178f3.txt secrets.txt.age
Encrypt to the SSH keys of a GitHub user:
$ curl https://github.com/benjojo.keys | age -R - example.jpg > example.jpg.age
Filippo Valsorda age@filippo.io