Skip to content

A TypeScript implementation of the age file encryption format, based on libsodium.

License

Notifications You must be signed in to change notification settings

FiloSottile/typage

The age logo, an wireframe of St. Peters dome in Rome, with the text: age, file encryption

age-encryption is a TypeScript implementation of the age file encryption format.

It depends only on the noble cryptography libraries, and uses the Web Crypto API when available.

Installation

npm install age-encryption

Usage

age-encryption is a modern ES Module, compatible with Node.js and Bun, with built-in types.

The whole API is documented with TypeDoc.

Encrypt and decrypt a file with a new recipient / identity pair

import * as age from "age-encryption"

const identity = await age.generateIdentity()
const recipient = await age.identityToRecipient(identity)
console.log(identity)
console.log(recipient)

const e = new age.Encrypter()
e.addRecipient(recipient)
const ciphertext = await e.encrypt("Hello, age!")

const d = new age.Decrypter()
d.addIdentity(identity)
const out = await d.decrypt(ciphertext, "text")
console.log(out)

Encrypt and decrypt a file with a passphrase

import { Encrypter, Decrypter } from "age-encryption"

const e = new Encrypter()
e.setPassphrase("burst-swarm-slender-curve-ability-various-crystal-moon-affair-three")
const ciphertext = await e.encrypt("Hello, age!")

const d = new Decrypter()
d.addPassphrase("burst-swarm-slender-curve-ability-various-crystal-moon-affair-three")
const out = await d.decrypt(ciphertext, "text")
console.log(out)

Browser usage

age-encryption is compatible with modern bundlers such as esbuild.

To produce a classic library file that sets age as a global variable, you can run

cd "$(mktemp -d)" && npm init -y && npm install esbuild age-encryption
npx esbuild --target=es6 --bundle --minify --outfile=age.js --global-name=age age-encryption

or download a pre-built one from the Releases page.

Then, you can use it like this

<script src="age.js"></script>
<script>
(async () => {
    const identity = await age.generateIdentity()
    const recipient = await age.identityToRecipient(identity)
    console.log(identity)
    console.log(recipient)

    const e = new age.Encrypter()
    e.addRecipient(recipient)
    const ciphertext = await e.encrypt("Hello, age!")

    const d = new age.Decrypter()
    d.addIdentity(identity)
    const out = await d.decrypt(ciphertext, "text")
    console.log(out)
})()
</script>

Web Crypto identities

You can use a CryptoKey as an identity. It must have an algorithm of X25519, and support the deriveBits key usage. It doesn't need to be extractable.

const keyPair = await crypto.subtle.generateKey({ name: "X25519" }, false, ["deriveBits"])
const identity = (keyPair as CryptoKeyPair).privateKey
const recipient = await age.identityToRecipient(identity)

const recipient = await age.identityToRecipient(identity)
console.log(recipient)

const e = new age.Encrypter()
e.addRecipient(recipient)
const file = await e.encrypt("age")

const d = new age.Decrypter()
d.addIdentity(identity)
const out = await d.decrypt(file, "text")
console.log(out)

Custom recipients and identities

You can implement the Recipient and Identity interfaces to use custom types as recipients and identities.

This lets you use use remote APIs and secrets managers to wrap files keys, and interoperate with age plugins.

About

A TypeScript implementation of the age file encryption format, based on libsodium.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published