Sekuvo
English

Envelope → QR

This page turns an already-encrypted Sekuvo envelope into QR frames your phone can scan. It performs no encryption and never asks for a secret: you produce the envelope on your own machine, and only ciphertext is pasted here.

The most conservative path is still the downloaded aktar.html, opened from your own disk. This page exists for the case where you encrypt in your own terminal and only need the QR display.

1 · Produce the envelope on your own machine

The script below builds exactly the envelope the app opens (PBKDF2-HMAC-SHA256 · 310,000 rounds + AES-256-GCM). Save it as zarf-uret.py and read it before running it — it is about thirty lines. Generate the password instead of inventing one; the first command does that.

# macOS / Linux
# generate a password (letters+digits, ~119 bits):
python3 -c "import secrets,string; print(''.join(secrets.choice(string.ascii_letters+string.digits) for _ in range(20)))"

pip3 install cryptography
python3 zarf-uret.py "Server SSH" > zarf.json   # paste the secret, then Ctrl-D
pbcopy < zarf.json                              # macOS; Linux: xclip -sel clip < zarf.json
# Windows (PowerShell)
# generate a password (letters+digits, ~119 bits):
python -c "import secrets,string; print(''.join(secrets.choice(string.ascii_letters+string.digits) for _ in range(20)))"

pip install cryptography
python zarf-uret.py "Server SSH" > zarf.json    # paste the secret, then Ctrl-Z + Enter
Get-Content zarf.json | Set-Clipboard
#!/usr/bin/env python3
# zarf-uret.py - reads the secret from stdin, writes a Sekuvo envelope to stdout.
# Usage: python3 zarf-uret.py "Title" > zarf.json   (paste the secret, then Ctrl-D)
# Requires: pip install cryptography
import sys, os, json, time, base64, hashlib, getpass
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

title = sys.argv[1] if len(sys.argv) > 1 else "Transfer"
secret = sys.stdin.read()
# The app refuses entries above 256 KB; say so here instead of after the scan.
assert len(secret.encode()) <= 256 * 1024, "secret is over 256 KB, the app will not import it"
password = getpass.getpass("Envelope password (ASCII, generated): ")
assert password.isascii() and len(password) >= 8, "ASCII and at least 8 characters"

now = int(time.time() * 1000)
payload = json.dumps({"entries": [{
    "type": "NOTE", "title": title,
    "createdAt": now, "updatedAt": now, "quick": False,
    "data": {"notes": secret},
}]}, ensure_ascii=False)

salt = os.urandom(16)
key = hashlib.pbkdf2_hmac("sha256", password.encode(), salt, 310_000, 32)
iv = os.urandom(12)
blob = iv + AESGCM(key).encrypt(iv, payload.encode(), None)
print(json.dumps({
    "app": "vault", "version": 1,
    "kdf": {"algo": "PBKDF2WithHmacSHA256", "iterations": 310_000,
            "salt": base64.b64encode(salt).decode()},
    "cipher": "AES-256-GCM",
    "data": base64.b64encode(blob).decode(),
}))

Paste the secret into the script's input rather than typing it on the command line — that way it never lands in your shell history.

2 · Paste the envelope

3 · On the phone

Sekuvo → + → Import via QR → scan the frames → enter the same password → Add to existing.

← Back to sekuvo.com