Skip to content

dennisvink/python-age

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

Install

python3 -m pip install python-age

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.

About

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

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages