diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-14 12:42:51 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-14 12:42:51 +0200 |
| commit | 86563d5db0ae19fc58336b71a5c29a8712973590 (patch) | |
| tree | ef269f2f29e5d81fd6681f64632895520266bc84 /packages/meshbay-node/src/meshbay_node | |
| parent | 2caa93dbc06161b5d3f776a204ac8d921df92126 (diff) | |
| download | meshbay-86563d5db0ae19fc58336b71a5c29a8712973590.tar.gz | |
feat(client): Argon2id for the keypair bundle, and remove the backup toggle
Two corrections to yesterday's judgement, in the order they matter.
**The toggle is gone.** Asked to make the remote key backup optional, I shipped a
setting whose "off" position meant: no second browser, ever, and clearing your
storage destroys the account. I wrote the warning that says so without drawing
the conclusion. A control whose only effect is to break the ordinary case is not
a control, and removing an exposure by removing the feature is not a fix. Every
browser backs its keys up again, unconditionally.
**The exposure is fixed where it actually lives: the KDF.** The keypair bundle
rests on every node whose group its owner joins, protected by the passphrase
alone (finding C4). It used PBKDF2-SHA512 at 600k — compute-only, which is
exactly what a GPU eats. Measured on this machine: PBKDF2 600k costs 241 ms and
Argon2id 64 MB/t=3 costs 322 ms, near enough the same honest work, except only
one of them forces an attacker to find 64 MB per guess.
So the bundle key is now Argon2id 64 MB / t=3 / p=1, via a vendored WebAssembly
build (no external host — the CSP forbids one, and 12.2 will tighten it further).
Parameters chosen by measurement through that build: 19 MB is OWASP's floor at
118 ms, 256 MB is 1.3 s and too slow for a phone, 64 MB sits where a login should.
What this buys, stated honestly: cracking a bundle yields the owner's identity
keys, and with them content on OTHER nodes and the ability to sign as them — not
the content on the operator's own node, which they host in the clear by design.
Argon2id raises that price steeply; it does not remove it, and a weak passphrase
still loses. Hence the floor raised to 12 characters and ~60 bits in the same
breath, which can only be enforced client-side: with the password split (T1) the
hub never sees a passphrase.
Migration is automatic and invisible. Bundles carry an "MBK2" marker; the old
form is still readable, and is re-encrypted the first time a browser backs it up.
Both keys are derived at sign-in, because which one a bundle needs is only known
once it is read and the passphrase is deliberately not kept around.
Two implementations of the KDF now exist — the browser's WASM and argon2-cffi in
QE — so a parity test holds them byte-identical. A disagreement would not look
like an error; it would look like an account nobody can open.
keypair_bundle_delete stays, without a UI. It is the mechanism behind withdrawing
your data from a node, exercised end to end, and it will belong to a deliberate
"forget me on this node" action rather than a setting that quietly disables
multi-device.
Verified against the live deployment: the full workflow passes, including
recovering keys on a second client from the passphrase alone.
Tests: 341.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node')
0 files changed, 0 insertions, 0 deletions