Key Management
Understanding how private keys, public keys, and cryptographic operations work in the BSV TypeScript SDK.
Cryptographic Keys
Bitcoin uses elliptic curve cryptography (secp256k1) for key management:
import { PrivateKey, PublicKey } from '@bsv/sdk'
// Generate a new private key
const privateKey = PrivateKey.fromRandom()
// Derive the corresponding public key
const publicKey = privateKey.toPublicKey()
Private Keys
Private keys are 256-bit numbers that control Bitcoin funds:
Generation
// Secure random generation
const privKey = PrivateKey.fromRandom()
// From existing data (use carefully)
const privKey2 = PrivateKey.fromString('hex_string')
Formats
// WIF (Wallet Import Format)
const wif = privateKey.toWif()
// Hex string
const hex = privateKey.toString()
// DER encoding
const der = privateKey.toDER()
Public Keys
Public keys are derived from private keys and can be shared safely:
Derivation
// Always derive from private key
const publicKey = privateKey.toPublicKey()
// Cannot go backwards (public -> private)
Formats
// Compressed (33 bytes) - preferred
const compressed = publicKey.toString()
// Uncompressed (65 bytes) - legacy
const uncompressed = publicKey.toString(false)
// DER encoding
const der = publicKey.toDER()
Digital Signatures
Private keys create signatures that prove ownership:
// Sign a message
const message = 'Hello Bitcoin'
const signature = privateKey.sign(message)
// Verify with public key
const isValid = publicKey.verify(message, signature)
Key Derivation
The SDK supports hierarchical key derivation:
// Derive child keys (simplified example)
const childKey = privateKey.deriveChild(0)
const childPubKey = childKey.toPublicKey()
Security Considerations
Private Key Security
- Never expose: Private keys should never be logged or transmitted
- Secure storage: Use encrypted storage for private keys
- Random generation: Always use cryptographically secure randomness
- Access control: Limit who can access private key operations
Best Practices
// Good: Generate securely
const key = PrivateKey.fromRandom()
// Bad: Predictable generation
const badKey = PrivateKey.fromString('1234567890abcdef...')
// Good: Derive public key when needed
const pubKey = key.toPublicKey()
// Bad: Store private key unnecessarily
localStorage.setItem('privateKey', key.toString())
Wallet Integration
In most applications, wallets handle key management:
The WalletClient
provides high-level key management through wallet integration:
// Wallet manages keys securely
const wallet = new WalletClient()
// Application doesn't see private keys
const action = await wallet.createAction({
outputs: [/* transaction outputs */]
})
When using the WalletClient
, keys are managed by the connected wallet service:
The WalletClient
approach is recommended for production applications as it provides:
Key Recovery
Keys can be recovered from various formats:
// From WIF format
const key1 = PrivateKey.fromWif(wifString)
// From hex string
const key2 = PrivateKey.fromString(hexString)
// From DER encoding
const key3 = PrivateKey.fromDER(derBytes)
Cryptographic Operations
The SDK provides secure implementations of:
- ECDSA: Digital signature algorithm
- ECDH: Key exchange protocol
- Hash Functions: SHA-256, RIPEMD-160
- AES: Symmetric encryption
Memory Management
Sensitive key data should be cleared when no longer needed:
- Use secure memory practices
- Clear variables containing key data
- Avoid keeping keys in memory longer than necessary
Testing and Development
For development and testing:
- Use testnet for experiments
- Generate new keys for each test
- Never use mainnet keys in test code
- Implement proper key rotation
Next Steps
- Understand Digital Signatures in detail
- Learn about Trust Model considerations
- Explore Wallet Integration patterns