Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

securepaper-js

Open-source toolkit for SecurePaper - encrypted paper backups. Type sensitive text, encrypt it with AES-256 locally, print it as QR codes; the paper is unreadable to anyone without the key or passphrase, and readable by you decades from now.

Everything in this repository runs entirely on your machine. No network calls, no telemetry, no server. The data format is publicly specified (with test vectors), so your printed papers do not depend on SecurePaper existing.

Package What it is
@securepaper_org/core The formats (AES-256-GCM, PBKDF2 passphrase mode, legacy CBC, QR chunking). Pure WebCrypto, zero dependencies, works in browsers and Node.js ≥ 20.
@securepaper_org/cli securepaper command: encrypt files/stdin into printable QR sheets, decrypt scanned codes.
@securepaper_org/mcp MCP server so AI assistants (Claude, and any MCP client) can create and read SecurePaper backups for you.

CLI quickstart

# encrypt a file into a printable sheet + a separate key sheet
npx -p @securepaper_org/cli securepaper encrypt secrets.txt --title "2FA backup codes" --out ./paper

# passphrase mode: nothing is stored anywhere - paper + your memory is the whole backup
cat .env | npx -p @securepaper_org/cli securepaper encrypt --passphrase --title "prod env"

# read a paper back (paste the QR contents scanned with any QR app)
npx -p @securepaper_org/cli securepaper decrypt scanned.txt --key 3f8a...

The output is a self-contained HTML sheet - open it in a browser, print it (Ctrl+P), done. In key mode a separate key sheet is written: print both and store them in different places.

MCP server (AI assistants)

Add to Claude Code:

claude mcp add securepaper -- npx -y @securepaper_org/mcp

or to Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "securepaper": { "command": "npx", "args": ["-y", "@securepaper_org/mcp"] }
  }
}

Then ask: "back up these recovery codes on paper with a passphrase" - the assistant calls encrypt_to_paper and hands you a printable sheet.

Tools: encrypt_to_paper, decrypt_paper, estimate_qr_count.

Privacy note: text passed through MCP tools is visible to the AI assistant and its conversation context. That is fine for secrets the assistant already sees or generated itself (recovery codes, configs, credentials created during setup). For a pre-existing wallet seed phrase or similar, use the web app or the CLI directly - the assistant never needs to see it.

Library quickstart

import { encrypt, encryptWithPassphrase, decrypt, chunkForQr, joinChunks } from '@securepaper_org/core';

const { code, key } = await encrypt('Bank PIN: 4729');           // AES-256-GCM, random key
const { code: pc } = await encryptWithPassphrase('hi', 'long passphrase'); // PBKDF2, nothing stored

const chunks = chunkForQr(code);          // ["SP:1/2|...", "SP:2/2|..."] for QR rendering
const back = await decrypt(joinChunks(chunks), { key });

Security model

  • Encryption: AES-256-GCM (authenticated), 12-byte random IV per message, via the platform's WebCrypto implementation - no userland crypto.
  • Passphrase mode: PBKDF2-HMAC-SHA256, 600,000 iterations, 16-byte random salt.
  • Legacy AES-256-CBC documents (pre-09/2026) remain readable; new documents never use CBC.
  • Losing the key / forgetting the passphrase makes a paper permanently unreadable - by design.
  • Full spec with test vectors: FORMAT.md. Cross-implementation compatibility with the SecurePaper web app is pinned by fixtures in the test suite.

Vulnerability reports: support@securepaper.app

Development

npm install
npm test          # all workspaces (node:test)

License

MIT

About

Encrypted paper backups: zero-dep crypto core (AES-256-GCM), CLI, and MCP server. Format spec with test vectors - your papers outlive the service.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages