age-crystal v0.2.1
age-crystal
Pure Crystal implementation of the age encryption format.
Why
age is a simple, modern file encryption format. This shard implements it directly in Crystal over OpenSSL primitives.
The format is interoperable: keys and ciphertext produced by this shard work with the age CLI and any other conforming age implementation.
Requirements
- Crystal >= 1.20.0
Installation
Add to your shard.yml:
dependencies:
age-crystal:
github: dirless/age-crystal
Run shards install.
Usage
require "age-crystal"
# Generate a keypair
keypair = Age.keygen
puts keypair.public_key # age1...
puts keypair.secret_key # AGE-SECRET-KEY-1...
# Encrypt
ciphertext = Age.encrypt("hello world", keypair.public_key)
# Decrypt
plaintext = Age.decrypt_string(ciphertext, keypair.secret_key)
Keys are compatible with the age CLI and any other age implementation:
# Encrypt in Crystal, decrypt with age CLI
echo "AGE-SECRET-KEY-1..." > key.txt
age --decrypt -i key.txt ciphertext.age
API
Age.keygen
Returns a fresh Age::Keypair with a random X25519 keypair.
Age.encrypt
Age.encrypt(data : Bytes | String, recipient : PublicKey) : Bytes
Encrypts data for recipient. Each call produces a different ciphertext (ephemeral key per encryption).
Age.decrypt
Age.decrypt(ciphertext : Bytes, identity : SecretKey) : Bytes
Age.decrypt_string(ciphertext : Bytes, identity : SecretKey) : String
Key types
Age::PublicKey— wrapsage1...stringsAge::SecretKey— wrapsAGE-SECRET-KEY-1...stringsAge::Keypair— holds both, returned byAge.keygen
All three validate their format on construction and raise Age::Error if invalid.
Error handling
All functions raise Age::Error on failure (bad key format, decryption mismatch, etc.).
Testing
crystal spec
License
MIT
age-crystal
- 1
- 0
- 0
- 1
- 1
- 1 day ago
- March 1, 2026
Mon, 25 May 2026 18:21:37 GMT