-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Description
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.rswithSignedMessagestruct - Added
wasm_sign_message()andwasm_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
- Ghostkey donation flow: https://freenet.org/ghostkey/create/
- Blind signature implementation: RFC 9474
[AI-assisted - Claude]
Metadata
Metadata
Assignees
Labels
No labels