@siwats/chronocrypt
v2.0.0
Published
Time-Based Granular Data Encryption System - A cryptographic library for temporal data access control
Downloads
265
Maintainers
Readme
ChronoCrypt
Asymmetric Time-Based Data Encryption System
A cryptographic library for temporal data access control with zero-knowledge authorization. ChronoCrypt uses asymmetric encryption (ECIES + AES-GCM) to enable data sources to encrypt temporal data streams while maintaining strong security properties even if the data source is compromised.
Security Model
ChronoCrypt implements an asymmetric three-party architecture where:
- KeyHolder (Trusted Zone): Generates and holds the master private key, authorizes access by deriving time-specific private keys
- DataSource (Untrusted Zone): Has only the public key, can encrypt but CANNOT decrypt
- DataViewer (Controlled Zone): Receives time-specific private keys from KeyHolder for authorized decryption
Key Security Properties
✅ DataSource Compromise Resistant: If the DataSource is compromised, attackers cannot decrypt any data (no private key) ✅ Temporal Binding: Timestamps are cryptographically bound via HKDF - tampering prevents decryption ✅ Authenticated Encryption: AES-256-GCM with authentication tags detect any data tampering ✅ Zero-Knowledge Authorization: KeyHolder authorizes access without seeing encrypted data content ✅ Granular Access Control: Authorization at timestamp-level precision with extensible policies ✅ Comprehensive Audit Trail: All operations logged for compliance and forensics
Features
- Hybrid Asymmetric Encryption: ECIES (EC P-256) + AES-256-GCM
- HKDF Temporal Binding: Timestamps cryptographically bound in key derivation
- Three-Party Security Model: Separation between encryption, authorization, and decryption
- Flexible Policy System: Extensible access control policies
- Pluggable Storage: Use in-memory, filesystem, or any database (Prisma examples included)
- Full TypeScript/Bun Support: Native async/await with Web Crypto API
Installation
bun add @siwats/chronocryptQuick Start
import {
generateMasterKeypair,
exportPublicKey,
createDataSource,
createKeyHolder,
createDataViewer,
InMemoryEncryptedRepository,
InMemoryAuditLog,
createAllowAllPolicy
} from '@siwats/chronocrypt';
// 1. KeyHolder: Generate master keypair (keep private key secure!)
const masterKeypair = await generateMasterKeypair();
const publicKey = await exportPublicKey(masterKeypair.publicKey);
// 2. Setup storage
const repository = new InMemoryEncryptedRepository();
const auditLog = new InMemoryAuditLog();
// 3. DataSource: Encrypt data (PUBLIC KEY ONLY - cannot decrypt!)
const dataSource = createDataSource(publicKey, repository);
const data = new TextEncoder().encode('Sensitive temporal data');
const encrypted = await dataSource.encryptData(data);
// 4. KeyHolder: Authorize access
const keyHolder = createKeyHolder(masterKeypair, auditLog, [createAllowAllPolicy()]);
const authResponse = await keyHolder.authorizeAccess({
requesterId: 'analyst-001',
timeRange: { startTime: encrypted.timestamp, endTime: encrypted.timestamp },
purpose: 'Data analysis'
});
// 5. DataViewer: Decrypt with authorized time-specific keys
const dataViewer = createDataViewer('analyst-001', auditLog);
dataViewer.loadAuthorizedKeys(authResponse.privateKeys!);
const decrypted = await dataViewer.decryptFromRepository(repository, encrypted.timestamp);
console.log(new TextDecoder().decode(decrypted!.data));
// Output: "Sensitive temporal data"Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ KeyHolder (Trusted) │
│ • Holds master private key │
│ • Derives time-specific private keys │
│ • Enforces access control policies │
│ • Never sees encrypted data │
└────────────────┬───────────────────────────────┬────────────────┘
│ Master Public Key │ Time-Specific
↓ │ Private Keys
┌────────────────────────────┐ ↓
│ DataSource (Untrusted) │ ┌──────────────────────────┐
│ • Has PUBLIC key only │ │ DataViewer (Controlled) │
│ • Encrypts temporal data │ │ • Receives authorized │
│ • CANNOT decrypt │ │ time-specific keys │
│ • Stores encrypted data │ │ • Decrypts only │
└────────────────────────────┘ │ authorized data │
└──────────────────────────┘Cryptographic Details
Encryption (DataSource)
- Generate random AES-256 symmetric key
K - Encrypt data:
ciphertext = AES-256-GCM(K, data, IV) - Generate ephemeral ECDH keypair
(e_priv, e_pub) - Perform ECDH:
shared_secret = ECDH(e_priv, recipient_public) - Derive wrapping key:
wrap_key = HKDF(shared_secret, salt=timestamp, info='ChronoCrypt-Wrap-v1') - Wrap symmetric key:
wrapped_K = AES-KW(wrap_key, K) - Package:
{timestamp, wrapped_K, e_pub, ciphertext, IV, auth_tag}
Decryption (DataViewer)
- Perform ECDH:
shared_secret = ECDH(time_specific_private, e_pub) - Derive unwrapping key:
unwrap_key = HKDF(shared_secret, salt=timestamp, info='ChronoCrypt-Wrap-v1') - Unwrap symmetric key:
K = AES-KW-UNWRAP(unwrap_key, wrapped_K) - Decrypt data:
data = AES-256-GCM-DECRYPT(K, ciphertext, IV, auth_tag)
Temporal Binding: The timestamp is used as salt in HKDF. Changing the timestamp in the encrypted package causes HKDF to derive a different key, making unwrapping fail.
Storage Options
ChronoCrypt provides flexible storage through simple interfaces. Choose the storage backend that fits your needs:
Built-in Storage
In-Memory (included) - Perfect for testing and development:
import { InMemoryEncryptedRepository, InMemoryAuditLog } from '@siwats/chronocrypt';
const repository = new InMemoryEncryptedRepository();
const auditLog = new InMemoryAuditLog();Database Storage
Prisma (PostgreSQL/SQLite) - Production-ready database storage:
See examples/prisma/PRISMA_SETUP.md for complete setup guide with schema and implementation examples.
Custom Storage
Implement your own storage by following the interfaces:
import type { EncryptedDataRepository, AuditLogStorage } from '@siwats/chronocrypt';
class MyCustomRepository implements EncryptedDataRepository {
async store(pkg: EncryptedPackage): Promise<void> { /* ... */ }
async retrieve(timestamp: Timestamp): Promise<EncryptedPackage | null> { /* ... */ }
async retrieveRange(range: TimeRange): Promise<EncryptedPackage[]> { /* ... */ }
async exists(timestamp: Timestamp): Promise<boolean> { /* ... */ }
}Access Control Policies
ChronoCrypt supports extensible access control policies. Currently implemented:
// Allow all requests (for development/testing)
createAllowAllPolicy()
// TODO: Additional policies coming soon
// - Requester whitelist
// - Time-based restrictions
// - Purpose validation
// - Maximum duration limitsCreate custom policies by implementing the AccessControlPolicy interface:
const customPolicy: AccessControlPolicy = {
id: 'my-policy',
name: 'My Custom Policy',
evaluate: async (request: AccessRequest) => {
// Return true to allow, false to deny
return request.requesterId.startsWith('trusted-');
},
priority: 100
};Complete Example
See examples/complete-example.ts for a full IoT sensor data encryption workflow demonstrating:
- Master keypair generation
- DataSource encryption (untrusted zone)
- KeyHolder authorization (trusted zone)
- DataViewer decryption (controlled zone)
- Audit log review
- Security properties demonstration
Run the example:
bun run examples/complete-example.tsTesting
Run the comprehensive test suite:
bun testTest coverage includes:
- Asymmetric key generation and derivation
- Hybrid encryption/decryption (ECIES + AES-GCM)
- Temporal binding via HKDF
- Authentication failure detection
- End-to-end workflows
- Security property verification
API Reference
Core Cryptographic Functions
// Generate EC P-256 master keypair
generateMasterKeypair(): Promise<MasterKeypair>
// Export/import public key (JWK format)
exportPublicKey(publicKey: CryptoKey): Promise<ExportedPublicKey>
importPublicKey(jwk: ExportedPublicKey): Promise<CryptoKey>
// Derive time-specific private key
deriveTimeSpecificPrivateKey(
masterPrivateKey: CryptoKey,
timestamp: Timestamp
): Promise<TimeSpecificPrivateKey>
// Hybrid encryption/decryption
encryptData(
data: Uint8Array,
recipientPublicKey: ExportedPublicKey,
timestamp: Timestamp,
metadata?: Record<string, unknown>
): Promise<EncryptedPackage>
decryptData(
pkg: EncryptedPackage,
timeSpecificPrivateKey: TimeSpecificPrivateKey
): Promise<Uint8Array>Entity Creation
// Create DataSource (receives public key only)
createDataSource(
publicKey: ExportedPublicKey,
repository: EncryptedDataRepository,
timestampGenerator?: () => Timestamp
): DataSource
// Create KeyHolder (holds private key)
createKeyHolder(
masterKeypair: MasterKeypair,
auditLog: AuditLogStorage,
policies?: AccessControlPolicy[],
keyHolderId?: string
): KeyHolder
// Create DataViewer
createDataViewer(
viewerId: string,
auditLog?: AuditLogStorage
): DataViewerSecurity Considerations
Key Management
- Master Private Key: Must be stored securely (HSM, secure enclave, etc.)
- Public Key: Can be distributed to untrusted DataSources
- Time-Specific Keys: Temporary, can be destroyed after use
- Key Rotation: Generate new master keypair periodically
Threat Model
✅ Protected Against:
- DataSource compromise (no decryption capability)
- Timestamp tampering (KDF binding)
- Data tampering (GCM authentication)
- Unauthorized decryption (requires KeyHolder authorization)
⚠️ Not Protected Against:
- Master private key compromise (grants access to all time periods)
- KeyHolder compromise (can authorize any access)
- Side-channel attacks (timing, power analysis)
Best Practices
- Separate environments: Run KeyHolder in isolated, highly secure environment
- Limit DataSource privileges: DataSources should only have public key and repository access
- Audit log review: Regularly review audit logs for suspicious access patterns
- Key rotation: Implement periodic master keypair rotation
- Policy enforcement: Use strict access control policies in production
Contributing
Contributions welcome! Please ensure:
- All tests pass (
bun test) - Code follows existing style
- Security-sensitive changes include threat model analysis
License
MIT
Acknowledgments
ChronoCrypt implements industry-standard cryptographic primitives:
- ECIES: Elliptic Curve Integrated Encryption Scheme
- ECDH: Elliptic Curve Diffie-Hellman (P-256/secp256r1)
- HKDF: HMAC-based Key Derivation Function (RFC 5869)
- AES-GCM: Advanced Encryption Standard - Galois/Counter Mode
- AES-KW: AES Key Wrap (RFC 3394)
All cryptographic operations use the Web Crypto API for security and performance.
