age file encryption for Elixir, backed by the Rust
age crate (the library behind rage) via Rustler.
Output is standard age v1, so files are interchangeable with the age and rage
command-line tools and every other conforming implementation.
Keys
- Identities are secret keys (
AGE-SECRET-KEY-1...), or unencrypted OpenSSHed25519/rsaprivate keys. - Recipients are public keys (
age1...), orssh-ed25519 .../ssh-rsa ...public keys.
Example
iex> {identity, recipient} = ExAge.generate_identity()
iex> {:ok, ciphertext} = ExAge.encrypt("attack at dawn", recipient)
iex> ExAge.decrypt(ciphertext, identity)
{:ok, "attack at dawn"}All encryption and decryption runs on dirty CPU schedulers, so it never blocks the BEAM's normal schedulers, including the deliberately slow scrypt passphrase key derivation.
Summary
Functions
Returns true if data looks like ASCII-armored age output.
Decrypts an age file with one or more identities.
Like decrypt/2, but raises ExAge.Error on failure.
Decrypts a passphrase-encrypted age file.
Like decrypt_with_passphrase/3, but raises ExAge.Error on failure.
Encrypts plaintext to one or more recipients.
Like encrypt/3, but raises ExAge.Error on failure.
Encrypts plaintext with a passphrase, using scrypt.
Like encrypt_with_passphrase/3, but raises ExAge.Error on failure.
Generates a new X25519 key pair.
Derives the public recipient for an X25519 identity.
Types
Functions
Returns true if data looks like ASCII-armored age output.
iex> ExAge.armored?("-----BEGIN AGE ENCRYPTED FILE-----\n...")
true
Decrypts an age file with one or more identities.
Binary and ASCII-armored input are both accepted. Each identity may be a single key or the full contents of an identity file.
Like decrypt/2, but raises ExAge.Error on failure.
@spec decrypt_with_passphrase(iodata(), String.t(), keyword()) :: {:ok, binary()} | {:error, reason()}
Decrypts a passphrase-encrypted age file.
Options
:max_work_factor- the highest scrypt cost as log2(N) to accept. This protects against files crafted to take hours to decrypt. By default age accepts up to about 16 times its local target.
Like decrypt_with_passphrase/3, but raises ExAge.Error on failure.
@spec encrypt(iodata(), recipient() | [recipient()], keyword()) :: {:ok, binary()} | {:error, reason()}
Encrypts plaintext to one or more recipients.
Options
:armor- whentrue, returns PEM-style ASCII-armored text instead of binary. Defaults tofalse.
Like encrypt/3, but raises ExAge.Error on failure.
@spec encrypt_with_passphrase(iodata(), String.t(), keyword()) :: {:ok, binary()} | {:error, reason()}
Encrypts plaintext with a passphrase, using scrypt.
Only use this for passphrases chosen by a person. For programmatic use,
generate a key pair with generate_identity/0 instead.
Options
:armor- return ASCII-armored text. Defaults tofalse.:work_factor- the scrypt cost as log2(N). By default age picks a value that takes about one second on the current machine.
Like encrypt_with_passphrase/3, but raises ExAge.Error on failure.
Generates a new X25519 key pair.
Returns {identity, recipient}. Store the identity as a secret. Share the
recipient freely.
iex> {"AGE-SECRET-KEY-1" <> _, "age1" <> _} = ExAge.generate_identity()
Derives the public recipient for an X25519 identity.
iex> {identity, recipient} = ExAge.generate_identity()
iex> ExAge.to_recipient(identity) == {:ok, recipient}
true