Summary
Create a Chrome extension to make ghostkeys more accessible to users. The extension enables secure storage, management, and use of ghostkeys for authentication to websites and Freenet contracts.
Background
Ghostkeys are anonymous, verifiable digital identities backed by donations. Currently users receive a PEM file after donating, but there's no convenient way to use it for authentication. A browser extension solves this by:
- Securely storing multiple ghostkeys with password/passkey encryption
- Providing a simple UI for key selection
- Exposing a website API for authentication requests
- Preventing signature replay attacks via structured auth requests
Implementation Progress
Phase 1: WASM Extensions (Complete)
Added signing/verification functions to gkwasm:
- Created
gklib/src/signed_message.rs with SignedMessage struct
- Added
wasm_sign_message() and wasm_verify_signed_message() to gkwasm
- Updated CLI to import from gklib (path dependency for local dev)
Phase 2: Extension Scaffolding (Complete)
Created extension/ directory with:
extension/
├── manifest.json # Manifest V3
├── package.json # TypeScript + webpack
├── src/
│ ├── background/
│ │ ├── index.ts # Service worker
│ │ ├── storage-service.ts # Encrypted vault (AES-256-GCM)
│ │ └── crypto-service.ts # WASM wrapper
│ ├── popup/popup.ts # Key selector UI
│ ├── options/options.ts # Key management
│ ├── content/content.ts # Website bridge
│ └── shared/
│ ├── types.ts
│ ├── messages.ts
│ └── encryption.ts # Web Crypto (PBKDF2 + AES-GCM)
└── wasm/ # Copied from hugo-site build
Remaining Work
Icons
- Need 16/48/128px PNG icons for the extension
- Should match Freenet branding
Passkey Support
- Add WebAuthn PRF extension for vault unlock
- Alternative to password-based encryption
User Confirmation Flow
- Currently auto-approves auth requests if unlocked
- Need popup confirmation showing origin, purpose, contract address
Testing
- Load extension in Chrome and test full flow
- Test with River UI integration
Website Integration API
The extension injects window.freenetGhostkey with:
// For web apps (River UI, etc.)
freenetGhostkey.authenticate({
challenge: crypto.randomUUID(),
purpose: "Join room #general"
}) → Promise<{signedAuth: string, certificate: string}>
// For Freenet contracts
freenetGhostkey.authenticateContract({
contractAddress: "abc123...",
challenge: crypto.randomUUID(),
purpose: "Subscribe to updates"
}) → Promise<{signedAuth: string, certificate: string}>
Security Design
- Structured auth requests: Signatures are bound to origin + contract + timestamp, preventing replay attacks
- Origin validation: Content script validates page origin matches request
- Encrypted storage: Keys encrypted with AES-256-GCM using PBKDF2-derived key (600k iterations)
- No arbitrary signing: Websites cannot get signatures on arbitrary content
Build Instructions
cd extension
npm install
npm run build
# Load extension/dist/ in Chrome via chrome://extensions/
Related
[AI-assisted - Claude]
Summary
Create a Chrome extension to make ghostkeys more accessible to users. The extension enables secure storage, management, and use of ghostkeys for authentication to websites and Freenet contracts.
Background
Ghostkeys are anonymous, verifiable digital identities backed by donations. Currently users receive a PEM file after donating, but there's no convenient way to use it for authentication. A browser extension solves this by:
Implementation Progress
Phase 1: WASM Extensions (Complete)
Added signing/verification functions to gkwasm:
gklib/src/signed_message.rswithSignedMessagestructwasm_sign_message()andwasm_verify_signed_message()to gkwasmPhase 2: Extension Scaffolding (Complete)
Created
extension/directory with:Remaining Work
Icons
Passkey Support
User Confirmation Flow
Testing
Website Integration API
The extension injects
window.freenetGhostkeywith:Security Design
Build Instructions
Related
[AI-assisted - Claude]