Skip to content

Chrome extension for ghostkey management #13

@sanity

Description

@sanity

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]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions