Skip to content

Commit 30ea0a0

Browse files
feat(awm): dinamo document update
1 parent 3e954c7 commit 30ea0a0

File tree

1 file changed

+70
-57
lines changed

1 file changed

+70
-57
lines changed

demo-kms-script/dinamo-interface.md

Lines changed: 70 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Dinamo HSM KMS Implementation Documentation
22

3-
This document provides comprehensive documentation for the KMS API's integration with Dinamo HSM, covering the complete request-response flow from API handlers to HSM operations.
3+
This document provides a reference implementation for integrating the 4 KMS API's with Dinamo HSM, covering the complete request-response flow from API handlers to HSM operations.
44

55
## Demo Scripts
66

@@ -32,7 +32,7 @@ API Request → Handler → KMS Provider → Dinamo HSM → Database → Respons
3232
| `POST /generateDataKey` | `generateDataKey.ts` | `generateDataKey()` | Create/export AES key |
3333
| `POST /decryptDataKey` | `decryptDataKey.ts` | `decryptDataKey()` | Local SJCL decryption |
3434

35-
## Envelope Encryption Pattern
35+
## Envelope Encryption Pattern (Recommended)
3636

3737
### Layer 1: Root Keys (HSM)
3838
- **Algorithm**: RSA-2048 asymmetric keys
@@ -78,12 +78,11 @@ private async withClient<T>(fn: (client) => Promise<T>): Promise<T> {
7878
}
7979
```
8080

81-
**Key Features:**
82-
- Environment-based configuration
83-
- Automatic connection cleanup using try/finally
84-
- Error handling for disconnect failures
85-
- Generic typing for return values
86-
- Centralized connection logic for all HSM operations
81+
**Why Connection Management is Critical:**
82+
- **Prevents Resource Leaks**: Ensures HSM connections are properly closed to avoid dangling connections
83+
- **HSM Connection Limits**: Hardware security modules have limited concurrent connection pools
84+
- **Network Stability**: Prevents socket exhaustion and connection timeouts
85+
- **Security Best Practice**: Minimizes attack surface by closing connections immediately after use
8786

8887
### Root Key Creation
8988

@@ -119,7 +118,7 @@ async createRootKey(): Promise<{ rootKey: string }> {
119118

120119
```typescript
121120
async generateDataKey(rootKey: string, keySpec: DataKeyTypeType): Promise<GenerateDataKeyKmsRes> {
122-
return await this.withClient(async (client) => {
121+
return await this.withClient(async (client) => { // Connection auto-managed to prevent dangling connections
123122
// 1. Create temporary AES key in HSM
124123
const dataKeyName = getRandomHash(32);
125124
const created = await client.key.create(
@@ -132,11 +131,15 @@ async generateDataKey(rootKey: string, keySpec: DataKeyTypeType): Promise<Genera
132131
// 2. Export plaintext key material
133132
const exportedKey = await client.key.exportSymmetric(dataKeyName);
134133
const plaintextKey = exportedKey.toString('base64');
134+
135+
// **CRITICAL SECURITY NOTE**: The plaintextKey contains raw cryptographic material
136+
// and MUST be wiped from memory immediately after encryption operations.
137+
// In production, use secure memory allocation and explicit zeroing.
135138

136139
// 3. Encrypt with root key (envelope encryption)
137140
return {
138141
encryptedKey: encrypt(rootKey, plaintextKey), // SJCL encryption
139-
plaintextKey: plaintextKey, // For immediate use
142+
plaintextKey: plaintextKey, // For immediate use - WIPE AFTER USE
140143
};
141144
});
142145
}
@@ -148,6 +151,50 @@ async generateDataKey(rootKey: string, keySpec: DataKeyTypeType): Promise<Genera
148151
3. **Format Conversion**: Buffer → base64 string
149152
4. **Envelope Encryption**: Encrypt plaintext with root key
150153
5. **Automatic Cleanup**: HSM deletes temporary key
154+
6. **⚠️ MEMORY SECURITY**: Plaintext key must be wiped from memory after use
155+
156+
### Memory Security Best Practices
157+
158+
```typescript
159+
// Example of secure memory handling (recommended for production)
160+
async secureDataKeyGeneration(rootKey: string): Promise<GenerateDataKeyKmsRes> {
161+
let plaintextKey: string | null = null;
162+
163+
try {
164+
const result = await this.generateDataKey(rootKey, 'AES-256');
165+
plaintextKey = result.plaintextKey;
166+
167+
// Use the plaintext key immediately
168+
const encryptedData = encrypt(plaintextKey, sensitiveData);
169+
170+
return {
171+
encryptedKey: result.encryptedKey,
172+
encryptedData: encryptedData
173+
};
174+
} finally {
175+
// **CRITICAL**: Explicitly wipe plaintext key from memory
176+
if (plaintextKey) {
177+
// Overwrite with random data multiple times
178+
for (let i = 0; i < 3; i++) {
179+
plaintextKey = crypto.randomBytes(plaintextKey.length).toString('base64');
180+
}
181+
plaintextKey = null;
182+
}
183+
184+
// Force garbage collection (if available)
185+
if (global.gc) {
186+
global.gc();
187+
}
188+
}
189+
}
190+
```
191+
192+
**Security Considerations:**
193+
- **Immediate Use**: Plaintext keys should be used immediately after generation
194+
- **Memory Overwriting**: Overwrite memory locations with random data before deallocation
195+
- **Garbage Collection**: Force GC to clear memory pages containing sensitive data
196+
- **Process Isolation**: Consider using separate processes for key operations
197+
- **Hardware Security**: Use HSM-backed secure memory when available
151198

152199
### Private Key Storage (POST /key)
153200

@@ -156,8 +203,14 @@ async postKey(rootKey: string, prv: string): Promise<PostKeyKmsRes> {
156203
// 1. Generate fresh data key for this private key
157204
const dataKey = await this.generateDataKey(rootKey, 'AES-256');
158205

159-
// 2. Encrypt private key with data key
160-
const encryptedPrv = encrypt(dataKey.plaintextKey, prv);
206+
let encryptedPrv: string;
207+
try {
208+
// 2. Encrypt private key with data key (use immediately)
209+
encryptedPrv = encrypt(dataKey.plaintextKey, prv);
210+
} finally {
211+
// **CRITICAL**: Wipe plaintext data key from memory immediately after use
212+
// Production code should implement secure memory wiping here
213+
}
161214

162215
return {
163216
encryptedPrv, // Encrypted private key
@@ -169,51 +222,11 @@ async postKey(rootKey: string, prv: string): Promise<PostKeyKmsRes> {
169222
}
170223
```
171224

172-
**Encryption Layers:**
173-
- **Layer 1**: Private Key → AES-256-CCM → Encrypted Private Key
174-
- Uses plaintextKey from HSM-generated data key
175-
- SJCL library for AES-256-CCM encryption
176-
- **Layer 2**: Data Key → Local AES → Encrypted Data Key
177-
- Uses root key as password
178-
- Custom encrypt() function from utils/encrypt.ts
179-
180-
### Private Key Retrieval (GET /key/{pub})
181-
182-
```typescript
183-
async getKey(rootKey: string, keyId: string, options: GetKeyOptions): Promise<GetKeyKmsRes> {
184-
// 1. Decrypt data key using root key
185-
const decryptedKey = await this.decryptDataKey(rootKey, options.encryptedDataKey);
186-
187-
// 2. Convert data key format
188-
const aesKeyBuffer = Buffer.from(decryptedKey.plaintextKey, 'base64');
189-
const password = aesKeyBuffer.toString('base64');
190-
191-
// 3. Decrypt private key with recovered data key
192-
const decryptedPrv = decrypt(password, keyId);
193-
194-
return { prv: decryptedPrv };
195-
}
196-
```
197-
198-
**Decryption Process:**
199-
1. **Data Key Recovery**: Decrypt encrypted data key with root key
200-
2. **Format Conversion**: base64 → Buffer → base64 (consistent format)
201-
3. **Private Key Decryption**: Use recovered data key to decrypt private key
202-
203-
### Data Key Decryption
204-
205-
```typescript
206-
async decryptDataKey(rootKey: string, encryptedKey: string): Promise<DecryptDataKeyKmsRes> {
207-
return {
208-
plaintextKey: decrypt(rootKey, encryptedKey),
209-
};
210-
}
211-
```
212-
213-
**Implementation Notes:**
214-
- **Local Operation**: Uses SJCL decryption, not HSM
215-
- **Root Key as Password**: Simple symmetric decryption
216-
- **Performance**: Fast local operation vs. slower HSM calls
225+
**Memory Security Notes:**
226+
- **Immediate Encryption**: Use plaintext data key immediately for encryption
227+
- **Secure Disposal**: Wipe plaintext key from memory after single use
228+
- **No Persistence**: Never store plaintext data keys in variables or logs
229+
- **Error Handling**: Ensure memory wiping occurs even if encryption fails
217230

218231
## Database Schema
219232

0 commit comments

Comments
 (0)