Fix pipeline diagram and document backup habits and dedup behavior
Replace the misaligned box diagram with a clean vertical flow. Expand the intro to explain bulk-loading one or many authenticators and how duplicates are handled at each stage. Add a "Backing up your OTP keys" section covering screenshotting QR codes to secure storage with a filename convention, and saving one-time backup/recovery codes.
This commit is contained in:
84
README.md
84
README.md
@@ -1,27 +1,87 @@
|
||||
# otp-import
|
||||
|
||||
Move TOTP credentials from saved authenticator **QR-code screenshots** onto a
|
||||
**VivoKey Apex** OTP applet (the ykneo-oath applet), by way of a plain,
|
||||
human-editable **CSV**.
|
||||
Bulk-load your saved authenticator **QR-code screenshots** onto a **VivoKey
|
||||
Apex** OTP applet (the ykneo-oath applet) — or onto several implants at once — by
|
||||
way of a plain, human-editable **CSV**.
|
||||
|
||||
Two small command-line tools:
|
||||
If you screenshot your two-factor QR codes as you enroll them (see
|
||||
[Backing up your OTP keys](#backing-up-your-otp-keys) below), these two tools
|
||||
turn that pile of screenshots into working TOTP credentials on a new or
|
||||
replacement authenticator, and can load the identical set onto multiple devices.
|
||||
|
||||
- `qr_to_sheet.py` — decode QR screenshots into the CSV (no hardware needed).
|
||||
- `apex_otp_import.py` — write the CSV's credentials onto the applet over PC/SC.
|
||||
|
||||
**Duplicates are handled at both stages, so you can re-run freely:**
|
||||
|
||||
- **QR → CSV** deduplicates on the `otpauth://` data: re-scanning a folder only
|
||||
appends codes that aren't already in the CSV; ones already present are silently
|
||||
skipped. Two screenshots of the *same account with different secrets* (e.g. a
|
||||
re-enrollment) are both kept — they are genuinely different credentials.
|
||||
- **CSV → applet** keys credentials by name (`issuer:account`): if a name is
|
||||
already on the applet you are asked to overwrite or skip it (or pass
|
||||
`--overwrite-all` / `--skip-existing`). Loading the same CSV onto a second
|
||||
implant just repeats the write. And before writing, the importer halts if two
|
||||
rows would collide on the same name — so a re-enrollment with a new secret
|
||||
can't silently clobber the old one; you relabel one of them first.
|
||||
|
||||
## Backing up your OTP keys
|
||||
|
||||
This utility is only useful if you saved your OTP keys in the first place. When
|
||||
you turn on TOTP two-factor authentication somewhere, the site shows a QR code
|
||||
(and usually a "can't scan it? enter this code instead" secret). That QR encodes
|
||||
an `otpauth://` URI containing the shared secret — capture it **then**, because
|
||||
you generally cannot retrieve it later without disabling and re-enrolling 2FA.
|
||||
|
||||
A good habit, every time you enable 2FA:
|
||||
|
||||
1. **Screenshot the QR code** and save the image to secure storage. The tools
|
||||
read the `otpauth://` data inside the image, not the filename, so the naming
|
||||
scheme is purely for your own organization — but a consistent one keeps the
|
||||
folder browsable and sortable. A practical convention is
|
||||
`YYYY-MM-DD-<relying-party>-<account>`:
|
||||
|
||||
```
|
||||
2024-05-01-github-alice@example.com.png
|
||||
2025-11-02-aws-root@example.com.png
|
||||
```
|
||||
|
||||
Date first so the folder sorts chronologically, then the service (relying
|
||||
party), then which account it is.
|
||||
|
||||
2. **Save the one-time backup/recovery codes too.** Most sites offer a set of
|
||||
single-use recovery codes next to the QR — copy them into a text file beside
|
||||
the screenshot (e.g. `2024-05-01-github-alice@example.com-backup-codes.txt`).
|
||||
If you ever lose every authenticator, those codes are how you get back in.
|
||||
(This tool doesn't process them; they're your independent recovery path.)
|
||||
|
||||
3. **Keep it all in secure storage.** These files contain live secrets — treat
|
||||
them like passwords. Good homes: a password-manager vault, an encrypted
|
||||
volume, or an end-to-end-encrypted cloud folder. Never commit them to a
|
||||
repository (this repo's `.gitignore` deliberately excludes `*.png`, `*.csv`,
|
||||
and backup-code text files).
|
||||
|
||||
With that habit in place, provisioning a new, replacement, or spare Apex is just
|
||||
pointing these tools at the folder.
|
||||
|
||||
---
|
||||
|
||||
## The pipeline
|
||||
|
||||
```
|
||||
QR screenshots otp-keys.csv Apex OTP applet
|
||||
┌───────────────┐ ┌──────────────┐ ┌───────────────┐
|
||||
│ *.png / *.jpg │──(1)──▶ │ issuer │──(3)───────▶ │ TOTP creds │
|
||||
│ otpauth://... │ │ account │ PUT/auth │ (ykneo-oath) │
|
||||
└───────────────┘ │ otpauth_uri │ └───────────────┘
|
||||
│ source_file │
|
||||
(2) edit labels here
|
||||
└──────────────┘
|
||||
QR screenshots (*.png / *.jpg, each holding an otpauth:// URI)
|
||||
|
|
||||
| (1) qr_to_sheet.py
|
||||
| decode each QR; append only NEW otpauth:// data to the CSV
|
||||
v
|
||||
otp-keys.csv columns: issuer | account | otpauth_uri | source_file
|
||||
|
|
||||
| (2) optional: edit the issuer / account labels (never otpauth_uri)
|
||||
|
|
||||
| (3) apex_otp_import.py
|
||||
| validate the CSV, authenticate if needed, PUT each credential
|
||||
v
|
||||
Apex OTP applet (ykneo-oath) one TOTP credential per row
|
||||
```
|
||||
|
||||
1. **QR → CSV** (`qr_to_sheet.py`): decode each screenshot and append any
|
||||
|
||||
Reference in New Issue
Block a user