Feature: Key Recovery #26
Labels
No labels
area:api
area:core
area:docs
area:infra
area:ux
dependencies
documentation
duplicate
good first issue
help wanted
invalid
question
rust
status:complete
status:partial
status:planned
type:bug
type:design
type:feature
type:infra
type:refactor
type:research
type:ux
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
icub3d/decentcom#26
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Migrated from GitHub issue icub3d/decentcom#26
Original Author: @icub3d
Original Date: 2026-04-15T14:15:55Z
Feature: Key Recovery
Overview
Key recovery allows users to export their master Ed25519 private key as an encrypted backup and import it on a new device. The backup is encrypted with a user-chosen passphrase using a strong KDF, producing a portable file that is useless without the passphrase. This is the primary mechanism for users to recover their identity if they lose access to their device.
Background
The identity design doc (
docs/design/identity.md) describes two recommended recovery mechanisms for launch: seed phrase (BIP39 mnemonic, implemented in theidentityfeature #4) and encrypted key backup. This feature implements the encrypted key backup (Option 2 from the design doc). The master private key is stored in the OS keychain by the Tauri core and never exposed to the React frontend. The export and import operations happen entirely within the Tauri Rust process.Depends on:
identity(feature #4), all Phase 1 and Phase 2 features.Requirements
Design
API / Interface Changes
No server-side API changes. Key recovery is entirely a client-side operation.
Tauri IPC commands:
key_exportpassphrase: string, path: stringResult<(), Error>key_importpassphrase: string, path: stringResult<PublicKeyInfo, Error>key_export_validate_passphrasepassphrase: stringResult<PassphraseStrength, Error>Exported file format (binary):
Total file size: 137 bytes.
Data Model Changes
No server-side data model changes.
Component Changes
Client Tauri core (
client/src-tauri/src/):client/src-tauri/src/crypto/backup.rs— new module: key backup encryption and decryptionencrypt_key(privkey, passphrase) -> Vec<u8>— KDF + AEAD encryption, produces the backup file bytesdecrypt_key(file_bytes, passphrase) -> Result<Ed25519PrivateKey, Error>— parse, decrypt, verifyread_backup_pubkey(file_bytes) -> Result<Ed25519PublicKey, Error>— read the cleartext pubkey without decryptingclient/src-tauri/src/crypto/passphrase.rs— new module: passphrase strength validation (length, entropy estimation)client/src-tauri/src/commands/key_recovery.rs— Tauri IPC command handlers for export/importclient/src-tauri/src/keystore.rs— extend existing keystore module withreplace_key()method for importClient React (
client/src/):client/src/components/settings/KeyExport.tsx— new component: export UI with passphrase input, strength indicator, file save dialogclient/src/components/settings/KeyImport.tsx— new component: import UI with file picker, passphrase input, confirmation dialogclient/src/components/settings/SecuritySettings.tsx— extend settings page to include key export/import sectionsDependencies:
argon2crate — Argon2id KDFchacha20poly1305crate — XChaCha20-Poly1305 AEADringor can be added as standalone cratesTask List
Phase A: Core Encryption Module
argon2andchacha20poly1305crate dependencies toclient/src-tauri/Cargo.tomlclient/src-tauri/src/crypto/backup.rswithencrypt_key()function: generate salt and nonce, derive key with Argon2id, encrypt with XChaCha20-Poly1305, assemble the file formatdecrypt_key()in the same module: parse the file format, derive key with Argon2id, decrypt and verifyread_backup_pubkey()for reading the cleartext public key from a backup fileclient/src-tauri/src/crypto/passphrase.rswith passphrase strength validationPhase B: Tauri IPC Commands
client/src-tauri/src/commands/key_recovery.rswithkey_exportcommand: read key from keystore, encrypt, write to filekey_importcommand: read file, decrypt, confirm replacement, store in keystorekey_export_validate_passphrasecommandclient/src-tauri/src/keystore.rswithreplace_key()that updates the OS keychain entryPhase C: Client UI
client/src/components/settings/KeyExport.tsx— passphrase input with strength meter, file save dialog via Tauri's dialog API, success/error feedbackclient/src/components/settings/KeyImport.tsx— file picker, passphrase input, display the backup's public key for confirmation, import button with confirmation dialogclient/src/components/settings/SecuritySettings.tsxTest List
encrypt_keyfollowed bydecrypt_keyround-trips successfully with the correct passphrasedecrypt_keywith wrong passphrase returns a decryption errordecrypt_keywith truncated file returns a parse errordecrypt_keywith corrupted ciphertext returns an authentication errorread_backup_pubkeyreturns the correct public key without needing the passphraseOpen Questions