Client-Side Signing and Key Migration
Currently, many decentralized identity approaches delegate signing operations to the PDS, where the private keys are stored and managed. This architecture has several limitations:
- Reduced client autonomy and control over signing operations
- Increased security risk as the PDS holds the private keys
- Limited ability to operate without PDS connectivity
- Potential privacy concerns as the PDS can track all signature operations
- Challenges with key portability across different PDS providers
This page outlines methods for performing cryptographic signing operations directly on the client side rather than delegating this responsibility to the Personal Data Server (PDS). It specifies two approaches for managing signing keys on the client: (1) deterministic key generation using RFC6979, and (2) random key generation with import/export capabilities for multi-device usage. By enabling client-side signing, we can enhance security, privacy, and user sovereignty while maintaining a seamless multi-device experience.
A formal specification for client-side signing can be found in the wip-05.
Client-Side Signing Architecture
Section titled “Client-Side Signing Architecture”This proposal introduces a shift from PDS-delegated signing to client-side signing where:
- Private keys are generated and stored on the client device
- Signing operations are performed locally without transmitting private keys
- Signed data is then sent to the PDS for distribution in the network
- Authentication with the PDS uses a separate mechanism than the main identity signing keys
Method 1: Wallet-Based Deterministic Signing
Section titled “Method 1: Wallet-Based Deterministic Signing”This method leverages existing wallet infrastructure to perform deterministic signing operations without exposing private keys.
Integration Process
Section titled “Integration Process”-
User authorizes the application to connect with their wallet
-
Application requests specific signing capabilities through the wallet’s permission system
-
Pseudocode to generate a deterministic private key using the wallet’s signing API:
// Example of using wallet signing API instead of direct key derivation// NOTE: Wallet must implement RFC6979 compliant deterministic signatureslet pathIndex = 0;let isValidKey = false;let candidatePrivateKey;let derivationPath;while (!isValidKey) {// TODO: derivationPath is based on BIP44 standard for HD wallets, we need to define a standard for web5derivationPath = `m/44'/0'/0'/0/${pathIndex}`;// Request signature from wallet with current derivation pathconst signatureResult = await wallet.sign({didMethod: "did:ckb",keyType: "secp256k1",data: "signingKey",derivationPath: derivationPath,});// Use signatureResult as seed input to generate a candidate private keycandidatePrivateKey = await crypto.subtle.digest("SHA-256",new TextEncoder().encode(signatureResult));// Convert to appropriate format for checksconst keyArray = new Uint8Array(candidatePrivateKey);// Check if key is valid for the selected curve, for secp256k1, key must be > 0 and < curve orderconst curveOrder = new BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");const keyBigInt = bytesToBigInt(keyArray);isValidKey = keyBigInt > 0 && keyBigInt < curveOrder;if (!isValidKey) {// If invalid, try with an incremented path indexpathIndex++;}}// Now candidatePrivateKey contains a valid private key derived from the signature// Use it for application-specific cryptographic operations// This key will be the same across devices if using the same wallet seed -
To rotate keys, the application can request the wallet to generate a new key pair using the same derivation path but with a new index.
Security Benefits
Section titled “Security Benefits”With this approach:
- Private keys never leave the secure wallet environment
- Key derivation happens within trusted, audited code
- Hardware security modules (HSMs) or secure enclaves can be leveraged
- Consistent signatures can be produced across devices using the same wallet recovery phrase
- Applications cannot extract or misuse private key material
Multi-Device Support
Section titled “Multi-Device Support”Multi-device support is achieved through wallet recovery mechanisms:
- Users back up their wallet recovery phrase (typically BIP39 mnemonic)
- The same wallet can be restored on multiple devices
- Signing operations produce identical results across all devices
Wallet Compatibility Requirements
Section titled “Wallet Compatibility Requirements”For this approach to work seamlessly:
- Applications must integrate with standard wallet connection protocols
- A standard derivation path scheme should be established for web5 did
- Applications should verify wallet compatibility before attempting operations
- Wallets should provide testing capabilities to verify correct signature generation
Method 2: Random Key Generation with Import/Export
Section titled “Method 2: Random Key Generation with Import/Export”This approach generates random keys and provides functionality to securely export and import them across devices.
Key Generation Process
Section titled “Key Generation Process”- Generate a random private key using a cryptographically secure random number generator:
privateKey = secureRandomBytes(32)
- Derive the public key from the private key:
publicKey = derivePublicKey(privateKey)
- Store the private key securely on the device
Key Export/Import
Section titled “Key Export/Import”- Encrypt the private key with a user-provided password:
encryptedKey = encrypt(privateKey, password)
- Generate export format (e.g., JSON, QR code) with metadata:
{"version": "1.0","keyType": "secp256k1","encryptedKey": "base64EncodedEncryptedKey","salt": "base64EncodedSalt","iv": "base64EncodedIV"}
- Import on other devices by decrypting with the same password
Integration with Web5 Infrastructure
Section titled “Integration with Web5 Infrastructure”PDS Interface Changes
Section titled “PDS Interface Changes”The PDS API would need to be extended to:
- Accept client-signed data instead of requiring the PDS to perform signing
- Verify the signature against the registered public key
- Support registration of client-generated public keys
Security Considerations
Section titled “Security Considerations”- Key material must never be transmitted unencrypted
- Client-side key storage should leverage platform security features (Keychain, TPM, etc.)
- Recovery phrases or backup mechanisms must be implemented securely
- Authentication between client and PDS remains separate from identity signing keys
- Implementation should protect against side-channel attacks
Implementation Requirements
Section titled “Implementation Requirements”Client libraries and applications implementing this proposal should:
- Provide deterministic or random key generation methods
- Implement secure key storage using platform-specific mechanisms
- Support standardized import/export formats for randomly generated keys
- Include clear user guidance on key management
- Provide methods to rotate keys if compromised
Backward Compatibility
Section titled “Backward Compatibility”This proposal can maintain compatibility with existing PDS infrastructure by:
- Supporting both client-side signing and PDS delegation during transition
- Providing migration paths for users to move from PDS-managed keys to client-managed keys
- Using the same signature formats and verification methods