# PaperAge
Easy and secure paper backups of (smallish) secrets using the Age format ([age-encryption.org/v1](https://age-encryption.org/v1)).
[![Rust build](https://github.com/matiaskorhonen/paper-age/actions/workflows/rust.yml/badge.svg)](https://github.com/matiaskorhonen/paper-age/actions/workflows/rust.yml) [![codecov](https://codecov.io/gh/matiaskorhonen/paper-age/graph/badge.svg?token=KM9VSJ6CCT)](https://codecov.io/gh/matiaskorhonen/paper-age) [![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/matiaskorhonen/paper-age)](https://github.com/matiaskorhonen/paper-age/releases/latest) [![Crates.io](https://img.shields.io/crates/v/paper-age)](https://crates.io/crates/paper-age)
## Features
* Accepts input either from a file or stdin
* Encrypts that input with a passphrase
* Outputs a PDF with a QR code of the encrypted ciphertext
* Support for both A4 and letter paper sizes
* The error correction level of the QR code is optimised (less data → more error correction)
* The passphrase **isn't** rendered on the PDF so that it can be printed on an untrusted printer (for example at work or the library)
* You don't need PaperAge to recover from the backup: use any QR code scanner and [any implementation of Age](https://github.com/FiloSottile/awesome-age#implementations).
## Limitations
* The maximum input size is about 1.9 KiB as QR codes cannot encode arbitrarily large payloads
* Only passphrase-based encryption is supported at the moment
## Threat models and use cases
* The main use case is keeping secrets, such as TFA recovery codes, in a safe place
* Adding the passphrase by hand allows the use of public printers, for example in libraries, offices, copy shops, and so forth
* For extra protection, memorize the passphrase or store it separately from the printout
* Needing to scan and decrypt protects against unsophisticated adversaries even if the passphrase is right there (the average burglar isn't going to care about your Mastodon account)
* If you need protection from nation-states or other advanced threats, look elsewhere
## Example
This is what the output PDF looks like (alternatively see the [letter equivalent](https://github.com/matiaskorhonen/paper-age/files/10716387/snakeoil-letter.pdf)). The QR code is easily readable with an iPhone (or any modern smartphone).
If you want to try decoding it yourself, the passphrase is `snakeoil`.
## Installation
Release builds are available for macOS (Apple Silicon and Intel), Linux (ARM and x86-64), and Windows (x86-64).
While the Windows build *should* work on both Windows 10 and 11, only Windows 11 is “officially” supported.
### Homebrew
Add the PaperAge Tap to install the latest version with Homebrew:
```sh
brew tap matiaskorhonen/paper-age
brew install paper-age
```
### Binary
Download the latest release from the [Releases](https://github.com/matiaskorhonen/paper-age/releases) page, extract the files, and install the `paper-age` binary somewhere in `PATH` (for example `/usr/local/bin`).
```sh
# Download the latest release (pick your OS)
# macOS (Intel or Apple Silicon):
curl -Lo paper-age.tar.gz https://github.com/matiaskorhonen/paper-age/releases/download/v1.3.3/paper-age-universal-apple-darwin.tar.gz
# Linux (x86-64):
curl -Lo paper-age.tar.gz https://github.com/matiaskorhonen/paper-age/releases/download/v1.3.3/paper-age-x86_64-unknown-linux-gnu.tar.gz
# Linux (ARM):
curl -Lo paper-age.tar.gz https://github.com/matiaskorhonen/paper-age/releases/download/v1.3.3/paper-age-aarch64-unknown-linux-gnu.tar.gz
# Verify the artifact attestation using the GitHub CLI tool (optional)
gh attestation verify paper-age.tar.gz --repo matiaskorhonen/paper-age
# Extract the files
tar -xf paper-age.tar.gz
# Install the binary in /usr/local/bin
sudo install paper-age /usr/local/bin/
# Or: sudo mv paper-age /usr/local/bin/
```
### Cargo
If you already have Rust installed, PaperAge can be installed with Cargo:
```sh
cargo install paper-age
```
### Artifact attestations
Starting with v1.3.1, PaperAge releases have [artifact attestations](https://github.com/matiaskorhonen/paper-age/attestations). Attestations are generated using [GitHub's tooling](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds).
## Usage
```
paper-age [OPTIONS] [INPUT]
```
### **Arguments**
* `` — The path to the file to read. Defaults to standard input. Max. ~1.9KB.
### **Options**
* `-t`, `--title ` — Page title (max. 64 characters)
Default value: `PaperAge`
* `-n`, `--notes-label ` — Notes label below the QR code (max. 32 characters)
Default value: `Passphrase:`
* `--skip-notes-line` — Skip the notes placeholder line (e.g. Passphrase: ________)
* `-o`, `--output