Key Management
Generate key pairs, choose the right algorithm, and handle keys securely.
All cryptography is pure JavaScript via @noble/curves.
generateKeyPair()
The primary key generation function:
Generate Ed25519 keys (default)
import { generateKeyPair } from '@attestto-com/vc-sdk' // Ed25519 (default — recommended) const ed25519Keys = generateKeyPair() // ES256 (ECDSA over P-256) const es256Keys = generateKeyPair('ES256')
KeyPair interface
KeyPair interface
interface KeyPair { algorithm: 'Ed25519' | 'ES256' publicKey: Uint8Array privateKey: Uint8Array }
Ed25519 vs ES256
| Property | Ed25519 | ES256 |
|---|---|---|
| Curve | Curve25519 | P-256 (secp256r1) |
| Signature type | EdDSA | ECDSA |
| Key size | 32 bytes | 32 bytes (private), 65 bytes (public) |
| Signature size | 64 bytes | 64 bytes |
| Performance | Faster signing and verification | Slower, but still fast in pure JS |
| Hardware support | Limited HSM support | Broad HSM/TPM support |
| Recommendation | Default choice | Use when HSM/WebAuthn compat needed |
Low-level crypto utilities
The SDK exports utilities for direct cryptographic operations:
sign() and verify()
import { sign, verify } from '@attestto-com/vc-sdk' const message = new TextEncoder().encode('Hello, world') // Sign a message const signature = sign(message, keys.privateKey, 'Ed25519') // Verify a signature const isValid = verify(message, signature, keys.publicKey, 'Ed25519') console.log(isValid) // true
Encoding utilities
import { toBase64url, fromBase64url, toHex } from '@attestto-com/vc-sdk' // Encode a public key for storage or transport const encoded = toBase64url(keys.publicKey) console.log(encoded) // 'dGhpcyBpcyBhIHB1YmxpYyBrZXk...' // Decode back to Uint8Array const decoded = fromBase64url(encoded) // Hex encoding for debugging const hex = toHex(keys.publicKey) console.log(hex) // '7468697320697320612...'
Security guidance
Never expose private keys in frontend code. Private keys should only
exist server-side or in secure enclaves (wallets, HSMs, TEEs). Use
verifyWithKey on the client with the public key only.
- Server-side issuance — run
VCIssueron your backend. Never ship private keys to the browser. - Environment variables — store keys in
process.envor a secrets manager, not in source code. - Key rotation — use the
keyIdfield to version your keys. Old credentials remain verifiable with old public keys. - Wallet delegation — for user-held keys, let a wallet (Attestto ID, browser extension) manage the private key. Your app never touches it.
Next steps
- Issuing credentials — use keys with VCIssuer
- Verifying credentials — use public keys for verification
- Schemas & plugins — add domain-specific types