Skip to main content

Python implementation of the age (Actually Good Encryption) v1 file format

Project description

age.py usage

age.py is a small Python implementation of the age v1 format (age-encryption.org/v1). It supports:

  • X25519 recipients (age1...)
  • scrypt passphrase encryption (-p)

It is intended for simple, local use and interoperability with the Go age tool for these recipient types.

Requirements

  • Python 3.9+ (3.8 may work, 3.9+ is recommended)
  • The cryptography package for X25519 and ChaCha20-Poly1305

Install the dependency:

python3 -m pip install cryptography

Quick start

Generate a keypair:

python3 age.py --keygen

Encrypt a file to a recipient:

python3 age.py -r age1... input.txt -o input.txt.age

Decrypt a file with an identity:

python3 age.py -d -i key.txt input.txt.age -o input.txt

Keys and recipients

--keygen prints the secret key to stdout and the recipient public key to stderr. The secret key is an AGE-SECRET-KEY-1... string. The public key is an age1... string.

Store secret keys in a file with one key per line. Lines starting with # and empty lines are ignored.

Example key.txt:

# my key
AGE-SECRET-KEY-1...

Recipient files use the same format (one age1... per line).

Encrypting

Encrypt from a file:

python3 age.py -r age1... input.bin -o input.bin.age

Encrypt from stdin:

echo "hello" | python3 age.py -r age1... -o message.age

Multiple recipients:

python3 age.py -r age1... -r age1... input.txt -o input.txt.age

Recipients from a file:

python3 age.py -R recipients.txt input.txt -o input.txt.age

Passphrase encryption:

python3 age.py -p input.txt -o input.txt.age

If -p is used, passphrase recipients cannot be mixed with -r or -R. The default scrypt work factor (18) uses ~256 MiB of memory. If you hit memory limits, lower it with --scrypt-work-factor.

You can set AGE_PASSPHRASE to provide the passphrase non-interactively:

AGE_PASSPHRASE="secret" python3 age.py -p input.txt -o input.txt.age

Decrypting

Decrypt to a file:

python3 age.py -d -i key.txt input.txt.age -o input.txt

Decrypt to stdout:

python3 age.py -d -i key.txt input.txt.age

Decrypt passphrase-encrypted files:

python3 age.py -d -p input.txt.age -o input.txt

You can set AGE_PASSPHRASE for non-interactive decryption as well.

Command reference

python3 age.py [input]
  -o, --output PATH               Output file (default: stdout)
  -d, --decrypt                   Decrypt mode
  -r, --recipient RECIPIENT       Encrypt to recipient (repeatable)
  -R, --recipients-file PATH      Encrypt to recipients listed in a file
  -i, --identity PATH             Decrypt with identities listed in a file
  -p, --passphrase                Use a passphrase (encrypt or decrypt)
  --scrypt-work-factor N          scrypt work factor for encryption (default 18)
  --scrypt-max-work-factor N      max scrypt factor for decryption (default 22)
  --keygen                        Generate a keypair

Programmatic use

Import the module and call the helpers directly:

from age import (
    ScryptRecipient,
    ScryptIdentity,
    X25519Recipient,
    X25519Identity,
    encrypt_bytes,
    decrypt_bytes,
    parse_recipient,
    parse_identity,
)

recipient = parse_recipient("age1...")
ciphertext = encrypt_bytes(b"hello", [recipient])

identity = parse_identity("AGE-SECRET-KEY-1...")
plaintext = decrypt_bytes(ciphertext, [identity])

File-like streaming is also supported:

from age import encrypt_file, decrypt_file, parse_recipient, parse_identity

with open("input.txt", "rb") as src, open("input.txt.age", "wb") as dst:
    encrypt_file(src, dst, [parse_recipient("age1...")])

with open("input.txt.age", "rb") as src, open("input.txt", "wb") as dst:
    decrypt_file(src, dst, [parse_identity("AGE-SECRET-KEY-1...")])

Compatibility and limitations

  • Compatible with the Go age tool for X25519 and scrypt recipients.
  • Does not implement SSH keys, plugins, armor, or post-quantum hybrid keys.
  • Uses the age v1 binary format (not ASCII armor).

Troubleshooting

  • "cryptography is required": install cryptography as above.
  • "no recipients specified": provide -r or -R, or use -p.
  • "no identities specified": provide -i or use -p.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_age-0.1.0.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

python_age-0.1.0-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file python_age-0.1.0.tar.gz.

File metadata

  • Download URL: python_age-0.1.0.tar.gz
  • Upload date:
  • Size: 11.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for python_age-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f34ddf6a337880e86e166571f9fece1482c6250b4488115499df4b88b0e46ec2
MD5 8e1fee9f52c970afa6c318e80743b7ba
BLAKE2b-256 b0522485596f0c5edae06205e4b17e91cf6418f44c13cf28f4df0af99f897ca3

See more details on using hashes here.

File details

Details for the file python_age-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: python_age-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for python_age-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fbc9db15a8dafcebf40812fabc8a3c318d69c22fccc3d593374dc6913f6f32ef
MD5 0156ba67a88b1277a5016a5fc2eacde6
BLAKE2b-256 ccbdcd60af01809614b3dd3d59a1f3084aead47bd2d6ef5239a08d9cd6dbbe3d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page