cd examples/ed25519-encrypted-keystore-demo
npm installnpm run devThe demo will start on http://localhost:5173
Open Chrome 106+ or Edge 106+ for full largeBlob support.
- Click "Create Credential" → biometric prompt
- Uncheck both security options
- Click "Authenticate with WebAuthn"
- Add some TODOs
Result: P-256 DID, unencrypted keystore (old behavior)
- Reset database or reload
- Create credential if needed
- ✅ Check "Use Ed25519 DID from keystore"
- ❌ Uncheck "Encrypt keystore"
- Authenticate
- Check the DID format (should start with
did:key:z6Mk)
Result: Ed25519 DID, but keystore still unencrypted
- Reset database or reload
- Create credential if needed
- ✅ Check "Use Ed25519 DID from keystore"
- ✅ Check "Encrypt keystore with WebAuthn"
- Select "largeBlob" (Chrome/Edge 106+)
- Authenticate → biometric prompt
- Add TODOs (no additional prompts!)
Result:
- Ed25519 DID from keystore
- Keystore encrypted with AES-GCM
- Secret key in WebAuthn hardware
- One biometric prompt per session
Open Chrome DevTools → Application → Local Storage:
- Look for
encrypted-keystore-*entries - You'll see ciphertext (encrypted data)
- Without WebAuthn auth, this data is useless!
- Reload the page (Cmd+R / Ctrl+R)
- Click "Authenticate with WebAuthn" → biometric prompt
- Your TODOs are still there!
- Same DID across sessions
🔍 Created WebAuthn identity: {
id: "did:key:z6Mk...",
type: "webauthn",
hash: "...",
didType: "Ed25519 (from keystore)",
encrypted: "Yes (largeBlob)"
}- P-256:
did:key:zDna...(starts with zDna) - Ed25519:
did:key:z6Mk...(starts with z6Mk)
- Unencrypted: Keys in plaintext
- Encrypted: Only ciphertext visible
| Feature | Chrome 106+ | Edge 106+ | Firefox | Safari |
|---|---|---|---|---|
| Ed25519 DID | ✅ | ✅ | ✅ | ✅ |
| largeBlob | ✅ | ✅ | ❌ | ❌ |
| hmac-secret | ✅ | ✅ | ✅ |
- You're not on Chrome/Edge 106+
- Try hmac-secret instead
- Or test without encryption first
- Check browser console for details
- Try resetting database
- Make sure WebAuthn is working
- Click "Reset Database"
- Clear IndexedDB manually
- Restart the dev server
- Created WebAuthn credential
- Tested without any options (baseline)
- Tested Ed25519 DID only
- Tested encryption with largeBlob
- Tested encryption with hmac-secret (if supported)
- Verified DID format (z6Mk for Ed25519)
- Checked localStorage for encrypted data
- Tested session persistence (reload page)
- Added/completed/deleted TODOs
- Verified only one biometric prompt per session
✅ Ed25519 DID starts with did:key:z6Mk
✅ Keystore encrypted in localStorage
✅ One biometric prompt per session
✅ TODOs persist across reload
✅ Console shows encryption status
Check the logs in:
- Browser console (F12)
- Terminal where
npm run devis running - Network tab for any API errors
To reset everything:
# In browser
Click "Reset Database"
# Or manually
# Chrome: DevTools → Application → Clear Storage → IndexedDBHappy testing! 🎉