@djangocfg/crypto 2.1.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +161 -0
- package/dist/index.cjs +267 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +297 -0
- package/dist/index.d.ts +297 -0
- package/dist/index.mjs +246 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.cjs +300 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +234 -0
- package/dist/react.d.ts +234 -0
- package/dist/react.mjs +279 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +79 -0
- package/src/decryption.ts +271 -0
- package/src/index.ts +66 -0
- package/src/key-derivation.ts +168 -0
- package/src/react/hooks.ts +236 -0
- package/src/react/index.ts +21 -0
- package/src/types.ts +159 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript interfaces for Django-CFG encryption.
|
|
3
|
+
*
|
|
4
|
+
* These types match the encrypted response format from Django-CFG backend.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Encrypted field envelope returned by Django-CFG API.
|
|
8
|
+
*
|
|
9
|
+
* When a serializer field is encrypted, it returns this structure
|
|
10
|
+
* instead of the plain value.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```json
|
|
14
|
+
* {
|
|
15
|
+
* "encrypted": true,
|
|
16
|
+
* "field": "price",
|
|
17
|
+
* "algorithm": "AES-256-GCM",
|
|
18
|
+
* "iv": "base64...",
|
|
19
|
+
* "data": "base64...",
|
|
20
|
+
* "auth_tag": "base64..."
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
interface EncryptedField {
|
|
25
|
+
/** Always true for encrypted fields */
|
|
26
|
+
encrypted: true;
|
|
27
|
+
/** Field name that was encrypted */
|
|
28
|
+
field?: string;
|
|
29
|
+
/** Encryption algorithm used */
|
|
30
|
+
algorithm: 'AES-256-GCM' | 'AES-256-CBC';
|
|
31
|
+
/** Base64-encoded initialization vector */
|
|
32
|
+
iv: string;
|
|
33
|
+
/** Base64-encoded ciphertext */
|
|
34
|
+
data: string;
|
|
35
|
+
/** Base64-encoded authentication tag (GCM only) */
|
|
36
|
+
auth_tag: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Full encrypted response envelope.
|
|
40
|
+
*
|
|
41
|
+
* When response-level encryption is enabled, the entire response
|
|
42
|
+
* body is wrapped in this structure.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```json
|
|
46
|
+
* {
|
|
47
|
+
* "encrypted": true,
|
|
48
|
+
* "algorithm": "AES-256-GCM",
|
|
49
|
+
* "salt": "base64...",
|
|
50
|
+
* "iv": "base64...",
|
|
51
|
+
* "data": "base64...",
|
|
52
|
+
* "auth_tag": "base64..."
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
interface EncryptedResponse {
|
|
57
|
+
/** Always true for encrypted responses */
|
|
58
|
+
encrypted: true;
|
|
59
|
+
/** Encryption algorithm used */
|
|
60
|
+
algorithm: 'AES-256-GCM' | 'AES-256-CBC';
|
|
61
|
+
/** Base64-encoded salt for key derivation */
|
|
62
|
+
salt: string;
|
|
63
|
+
/** Base64-encoded initialization vector */
|
|
64
|
+
iv: string;
|
|
65
|
+
/** Base64-encoded ciphertext */
|
|
66
|
+
data: string;
|
|
67
|
+
/** Base64-encoded authentication tag (GCM only) */
|
|
68
|
+
auth_tag: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Configuration for the decryption client.
|
|
72
|
+
*/
|
|
73
|
+
interface DecryptionConfig {
|
|
74
|
+
/**
|
|
75
|
+
* Secret key for key derivation.
|
|
76
|
+
* Should match the Django SECRET_KEY or a derived key.
|
|
77
|
+
*/
|
|
78
|
+
secretKey: string;
|
|
79
|
+
/**
|
|
80
|
+
* User ID for per-user key derivation (optional).
|
|
81
|
+
* When provided, keys are derived per-user for isolation.
|
|
82
|
+
*/
|
|
83
|
+
userId?: string | number;
|
|
84
|
+
/**
|
|
85
|
+
* Session ID for per-session key derivation (optional).
|
|
86
|
+
* Takes precedence over userId if both provided.
|
|
87
|
+
*/
|
|
88
|
+
sessionId?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Number of PBKDF2 iterations (default: 100000).
|
|
91
|
+
* Must match backend configuration.
|
|
92
|
+
*/
|
|
93
|
+
iterations?: number;
|
|
94
|
+
/**
|
|
95
|
+
* Key prefix for derivation (default: "djangocfg_encryption").
|
|
96
|
+
* Must match backend configuration.
|
|
97
|
+
*/
|
|
98
|
+
keyPrefix?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Result of a decryption operation.
|
|
102
|
+
*/
|
|
103
|
+
interface DecryptionResult<T = unknown> {
|
|
104
|
+
/** Decrypted data */
|
|
105
|
+
data: T;
|
|
106
|
+
/** Whether decryption was successful */
|
|
107
|
+
success: true;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Error from a decryption operation.
|
|
111
|
+
*/
|
|
112
|
+
interface DecryptionError {
|
|
113
|
+
/** Error message */
|
|
114
|
+
message: string;
|
|
115
|
+
/** Error code */
|
|
116
|
+
code: 'INVALID_FORMAT' | 'DECRYPTION_FAILED' | 'AUTH_FAILED' | 'KEY_ERROR';
|
|
117
|
+
/** Whether decryption was successful */
|
|
118
|
+
success: false;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Type guard to check if a value is an encrypted field.
|
|
122
|
+
*/
|
|
123
|
+
declare function isEncryptedField(value: unknown): value is EncryptedField;
|
|
124
|
+
/**
|
|
125
|
+
* Type guard to check if a value is an encrypted response.
|
|
126
|
+
*/
|
|
127
|
+
declare function isEncryptedResponse(value: unknown): value is EncryptedResponse;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* PBKDF2 key derivation using Web Crypto API.
|
|
131
|
+
*
|
|
132
|
+
* Matches Django-CFG backend key derivation for decryption compatibility.
|
|
133
|
+
*/
|
|
134
|
+
/**
|
|
135
|
+
* Derive an encryption key using PBKDF2.
|
|
136
|
+
*
|
|
137
|
+
* Uses Web Crypto API for secure key derivation that matches
|
|
138
|
+
* the Django-CFG backend implementation.
|
|
139
|
+
*
|
|
140
|
+
* @param password - The password/secret key to derive from
|
|
141
|
+
* @param salt - Salt bytes for key derivation
|
|
142
|
+
* @param iterations - Number of PBKDF2 iterations (default: 100000)
|
|
143
|
+
* @param keyLength - Desired key length in bytes (default: 32 for AES-256)
|
|
144
|
+
* @returns Promise resolving to derived key as CryptoKey
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const salt = new TextEncoder().encode('my-salt');
|
|
149
|
+
* const key = await deriveKey('secret', salt, 100000);
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
declare function deriveKey(password: string, salt: Uint8Array, iterations?: number, keyLength?: number): Promise<CryptoKey>;
|
|
153
|
+
/**
|
|
154
|
+
* Derive raw key bytes using PBKDF2.
|
|
155
|
+
*
|
|
156
|
+
* @param password - The password/secret key to derive from
|
|
157
|
+
* @param salt - Salt bytes for key derivation
|
|
158
|
+
* @param iterations - Number of PBKDF2 iterations (default: 100000)
|
|
159
|
+
* @param keyLength - Desired key length in bytes (default: 32 for AES-256)
|
|
160
|
+
* @returns Promise resolving to derived key as Uint8Array
|
|
161
|
+
*/
|
|
162
|
+
declare function deriveKeyBytes(password: string, salt: Uint8Array, iterations?: number, keyLength?: number): Promise<Uint8Array>;
|
|
163
|
+
/**
|
|
164
|
+
* Build a deterministic salt from context components.
|
|
165
|
+
*
|
|
166
|
+
* Matches Django-CFG backend salt generation for key derivation.
|
|
167
|
+
*
|
|
168
|
+
* @param keyPrefix - Key prefix (default: "djangocfg_encryption")
|
|
169
|
+
* @param userId - Optional user ID for per-user keys
|
|
170
|
+
* @param sessionId - Optional session ID for per-session keys
|
|
171
|
+
* @returns Salt as Uint8Array (first 16 bytes of SHA-256 hash)
|
|
172
|
+
*/
|
|
173
|
+
declare function buildSalt(keyPrefix?: string, userId?: string | number, sessionId?: string): Promise<Uint8Array>;
|
|
174
|
+
/**
|
|
175
|
+
* Derive encryption key from Django-CFG config.
|
|
176
|
+
*
|
|
177
|
+
* Convenience function that matches backend key derivation.
|
|
178
|
+
*
|
|
179
|
+
* @param config - Configuration object with secretKey and optional context
|
|
180
|
+
* @returns Promise resolving to CryptoKey for decryption
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* const key = await deriveKeyFromConfig({
|
|
185
|
+
* secretKey: 'django-secret-key',
|
|
186
|
+
* userId: 123,
|
|
187
|
+
* iterations: 100000
|
|
188
|
+
* });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
declare function deriveKeyFromConfig(config: {
|
|
192
|
+
secretKey: string;
|
|
193
|
+
userId?: string | number;
|
|
194
|
+
sessionId?: string;
|
|
195
|
+
iterations?: number;
|
|
196
|
+
keyPrefix?: string;
|
|
197
|
+
}): Promise<CryptoKey>;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* AES-256-GCM decryption using Web Crypto API.
|
|
201
|
+
*
|
|
202
|
+
* Decrypts data encrypted by Django-CFG backend.
|
|
203
|
+
*/
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Decrypt AES-256-GCM ciphertext.
|
|
207
|
+
*
|
|
208
|
+
* @param ciphertext - Encrypted data bytes
|
|
209
|
+
* @param key - CryptoKey for decryption
|
|
210
|
+
* @param iv - Initialization vector
|
|
211
|
+
* @param authTag - Authentication tag
|
|
212
|
+
* @returns Promise resolving to decrypted bytes
|
|
213
|
+
*/
|
|
214
|
+
declare function decryptAES256GCM(ciphertext: Uint8Array, key: CryptoKey, iv: Uint8Array, authTag: Uint8Array): Promise<Uint8Array>;
|
|
215
|
+
/**
|
|
216
|
+
* Decrypt a single encrypted field value.
|
|
217
|
+
*
|
|
218
|
+
* @param field - Encrypted field envelope
|
|
219
|
+
* @param key - CryptoKey for decryption
|
|
220
|
+
* @returns Promise resolving to decrypted value
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* const key = await deriveKeyFromConfig({ secretKey: '...' });
|
|
225
|
+
* const price = await decryptField(response.price, key);
|
|
226
|
+
* console.log(price); // 99.99
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
declare function decryptField<T = unknown>(field: EncryptedField, key: CryptoKey): Promise<T>;
|
|
230
|
+
/**
|
|
231
|
+
* Decrypt an entire encrypted response.
|
|
232
|
+
*
|
|
233
|
+
* @param response - Encrypted response envelope
|
|
234
|
+
* @param secretKey - Secret key for key derivation
|
|
235
|
+
* @param config - Additional config (userId, sessionId, etc.)
|
|
236
|
+
* @returns Promise resolving to decrypted response data
|
|
237
|
+
*/
|
|
238
|
+
declare function decryptResponse<T = unknown>(response: EncryptedResponse, secretKey: string, config?: Partial<Omit<DecryptionConfig, 'secretKey'>>): Promise<T>;
|
|
239
|
+
/**
|
|
240
|
+
* Recursively decrypt all encrypted fields in an object.
|
|
241
|
+
*
|
|
242
|
+
* @param data - Object potentially containing encrypted fields
|
|
243
|
+
* @param key - CryptoKey for decryption
|
|
244
|
+
* @returns Promise resolving to object with all fields decrypted
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```typescript
|
|
248
|
+
* const key = await deriveKeyFromConfig({ secretKey: '...' });
|
|
249
|
+
* const product = await decryptObject(response, key);
|
|
250
|
+
* // product.price is now decrypted
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare function decryptObject<T>(data: unknown, key: CryptoKey): Promise<T>;
|
|
254
|
+
/**
|
|
255
|
+
* Create a decryption client with pre-configured key.
|
|
256
|
+
*
|
|
257
|
+
* @param config - Decryption configuration
|
|
258
|
+
* @returns Object with decryption methods
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const crypto = await createDecryptionClient({
|
|
263
|
+
* secretKey: 'django-secret-key',
|
|
264
|
+
* userId: currentUser.id
|
|
265
|
+
* });
|
|
266
|
+
*
|
|
267
|
+
* const response = await fetch('/api/products/?encrypt=true');
|
|
268
|
+
* const data = await crypto.decryptObject(await response.json());
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
declare function createDecryptionClient(config: DecryptionConfig): Promise<{
|
|
272
|
+
/**
|
|
273
|
+
* Decrypt a single encrypted field.
|
|
274
|
+
*/
|
|
275
|
+
decryptField: <T = unknown>(field: EncryptedField) => Promise<T>;
|
|
276
|
+
/**
|
|
277
|
+
* Recursively decrypt all encrypted fields in an object.
|
|
278
|
+
*/
|
|
279
|
+
decryptObject: <T>(data: unknown) => Promise<T>;
|
|
280
|
+
/**
|
|
281
|
+
* Check if a value is an encrypted field.
|
|
282
|
+
*/
|
|
283
|
+
isEncryptedField: typeof isEncryptedField;
|
|
284
|
+
/**
|
|
285
|
+
* Check if a value is an encrypted response.
|
|
286
|
+
*/
|
|
287
|
+
isEncryptedResponse: typeof isEncryptedResponse;
|
|
288
|
+
}>;
|
|
289
|
+
/**
|
|
290
|
+
* Safe decryption wrapper that returns result or error.
|
|
291
|
+
*
|
|
292
|
+
* @param fn - Async function to execute
|
|
293
|
+
* @returns Promise resolving to DecryptionResult or DecryptionError
|
|
294
|
+
*/
|
|
295
|
+
declare function safeDecrypt<T>(fn: () => Promise<T>): Promise<DecryptionResult<T> | DecryptionError>;
|
|
296
|
+
|
|
297
|
+
export { type DecryptionConfig, type DecryptionError, type DecryptionResult, type EncryptedField, type EncryptedResponse, buildSalt, createDecryptionClient, decryptAES256GCM, decryptField, decryptObject, decryptResponse, deriveKey, deriveKeyBytes, deriveKeyFromConfig, isEncryptedField, isEncryptedResponse, safeDecrypt };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript interfaces for Django-CFG encryption.
|
|
3
|
+
*
|
|
4
|
+
* These types match the encrypted response format from Django-CFG backend.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Encrypted field envelope returned by Django-CFG API.
|
|
8
|
+
*
|
|
9
|
+
* When a serializer field is encrypted, it returns this structure
|
|
10
|
+
* instead of the plain value.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```json
|
|
14
|
+
* {
|
|
15
|
+
* "encrypted": true,
|
|
16
|
+
* "field": "price",
|
|
17
|
+
* "algorithm": "AES-256-GCM",
|
|
18
|
+
* "iv": "base64...",
|
|
19
|
+
* "data": "base64...",
|
|
20
|
+
* "auth_tag": "base64..."
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
interface EncryptedField {
|
|
25
|
+
/** Always true for encrypted fields */
|
|
26
|
+
encrypted: true;
|
|
27
|
+
/** Field name that was encrypted */
|
|
28
|
+
field?: string;
|
|
29
|
+
/** Encryption algorithm used */
|
|
30
|
+
algorithm: 'AES-256-GCM' | 'AES-256-CBC';
|
|
31
|
+
/** Base64-encoded initialization vector */
|
|
32
|
+
iv: string;
|
|
33
|
+
/** Base64-encoded ciphertext */
|
|
34
|
+
data: string;
|
|
35
|
+
/** Base64-encoded authentication tag (GCM only) */
|
|
36
|
+
auth_tag: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Full encrypted response envelope.
|
|
40
|
+
*
|
|
41
|
+
* When response-level encryption is enabled, the entire response
|
|
42
|
+
* body is wrapped in this structure.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```json
|
|
46
|
+
* {
|
|
47
|
+
* "encrypted": true,
|
|
48
|
+
* "algorithm": "AES-256-GCM",
|
|
49
|
+
* "salt": "base64...",
|
|
50
|
+
* "iv": "base64...",
|
|
51
|
+
* "data": "base64...",
|
|
52
|
+
* "auth_tag": "base64..."
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
interface EncryptedResponse {
|
|
57
|
+
/** Always true for encrypted responses */
|
|
58
|
+
encrypted: true;
|
|
59
|
+
/** Encryption algorithm used */
|
|
60
|
+
algorithm: 'AES-256-GCM' | 'AES-256-CBC';
|
|
61
|
+
/** Base64-encoded salt for key derivation */
|
|
62
|
+
salt: string;
|
|
63
|
+
/** Base64-encoded initialization vector */
|
|
64
|
+
iv: string;
|
|
65
|
+
/** Base64-encoded ciphertext */
|
|
66
|
+
data: string;
|
|
67
|
+
/** Base64-encoded authentication tag (GCM only) */
|
|
68
|
+
auth_tag: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Configuration for the decryption client.
|
|
72
|
+
*/
|
|
73
|
+
interface DecryptionConfig {
|
|
74
|
+
/**
|
|
75
|
+
* Secret key for key derivation.
|
|
76
|
+
* Should match the Django SECRET_KEY or a derived key.
|
|
77
|
+
*/
|
|
78
|
+
secretKey: string;
|
|
79
|
+
/**
|
|
80
|
+
* User ID for per-user key derivation (optional).
|
|
81
|
+
* When provided, keys are derived per-user for isolation.
|
|
82
|
+
*/
|
|
83
|
+
userId?: string | number;
|
|
84
|
+
/**
|
|
85
|
+
* Session ID for per-session key derivation (optional).
|
|
86
|
+
* Takes precedence over userId if both provided.
|
|
87
|
+
*/
|
|
88
|
+
sessionId?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Number of PBKDF2 iterations (default: 100000).
|
|
91
|
+
* Must match backend configuration.
|
|
92
|
+
*/
|
|
93
|
+
iterations?: number;
|
|
94
|
+
/**
|
|
95
|
+
* Key prefix for derivation (default: "djangocfg_encryption").
|
|
96
|
+
* Must match backend configuration.
|
|
97
|
+
*/
|
|
98
|
+
keyPrefix?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Result of a decryption operation.
|
|
102
|
+
*/
|
|
103
|
+
interface DecryptionResult<T = unknown> {
|
|
104
|
+
/** Decrypted data */
|
|
105
|
+
data: T;
|
|
106
|
+
/** Whether decryption was successful */
|
|
107
|
+
success: true;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Error from a decryption operation.
|
|
111
|
+
*/
|
|
112
|
+
interface DecryptionError {
|
|
113
|
+
/** Error message */
|
|
114
|
+
message: string;
|
|
115
|
+
/** Error code */
|
|
116
|
+
code: 'INVALID_FORMAT' | 'DECRYPTION_FAILED' | 'AUTH_FAILED' | 'KEY_ERROR';
|
|
117
|
+
/** Whether decryption was successful */
|
|
118
|
+
success: false;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Type guard to check if a value is an encrypted field.
|
|
122
|
+
*/
|
|
123
|
+
declare function isEncryptedField(value: unknown): value is EncryptedField;
|
|
124
|
+
/**
|
|
125
|
+
* Type guard to check if a value is an encrypted response.
|
|
126
|
+
*/
|
|
127
|
+
declare function isEncryptedResponse(value: unknown): value is EncryptedResponse;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* PBKDF2 key derivation using Web Crypto API.
|
|
131
|
+
*
|
|
132
|
+
* Matches Django-CFG backend key derivation for decryption compatibility.
|
|
133
|
+
*/
|
|
134
|
+
/**
|
|
135
|
+
* Derive an encryption key using PBKDF2.
|
|
136
|
+
*
|
|
137
|
+
* Uses Web Crypto API for secure key derivation that matches
|
|
138
|
+
* the Django-CFG backend implementation.
|
|
139
|
+
*
|
|
140
|
+
* @param password - The password/secret key to derive from
|
|
141
|
+
* @param salt - Salt bytes for key derivation
|
|
142
|
+
* @param iterations - Number of PBKDF2 iterations (default: 100000)
|
|
143
|
+
* @param keyLength - Desired key length in bytes (default: 32 for AES-256)
|
|
144
|
+
* @returns Promise resolving to derived key as CryptoKey
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const salt = new TextEncoder().encode('my-salt');
|
|
149
|
+
* const key = await deriveKey('secret', salt, 100000);
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
declare function deriveKey(password: string, salt: Uint8Array, iterations?: number, keyLength?: number): Promise<CryptoKey>;
|
|
153
|
+
/**
|
|
154
|
+
* Derive raw key bytes using PBKDF2.
|
|
155
|
+
*
|
|
156
|
+
* @param password - The password/secret key to derive from
|
|
157
|
+
* @param salt - Salt bytes for key derivation
|
|
158
|
+
* @param iterations - Number of PBKDF2 iterations (default: 100000)
|
|
159
|
+
* @param keyLength - Desired key length in bytes (default: 32 for AES-256)
|
|
160
|
+
* @returns Promise resolving to derived key as Uint8Array
|
|
161
|
+
*/
|
|
162
|
+
declare function deriveKeyBytes(password: string, salt: Uint8Array, iterations?: number, keyLength?: number): Promise<Uint8Array>;
|
|
163
|
+
/**
|
|
164
|
+
* Build a deterministic salt from context components.
|
|
165
|
+
*
|
|
166
|
+
* Matches Django-CFG backend salt generation for key derivation.
|
|
167
|
+
*
|
|
168
|
+
* @param keyPrefix - Key prefix (default: "djangocfg_encryption")
|
|
169
|
+
* @param userId - Optional user ID for per-user keys
|
|
170
|
+
* @param sessionId - Optional session ID for per-session keys
|
|
171
|
+
* @returns Salt as Uint8Array (first 16 bytes of SHA-256 hash)
|
|
172
|
+
*/
|
|
173
|
+
declare function buildSalt(keyPrefix?: string, userId?: string | number, sessionId?: string): Promise<Uint8Array>;
|
|
174
|
+
/**
|
|
175
|
+
* Derive encryption key from Django-CFG config.
|
|
176
|
+
*
|
|
177
|
+
* Convenience function that matches backend key derivation.
|
|
178
|
+
*
|
|
179
|
+
* @param config - Configuration object with secretKey and optional context
|
|
180
|
+
* @returns Promise resolving to CryptoKey for decryption
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* const key = await deriveKeyFromConfig({
|
|
185
|
+
* secretKey: 'django-secret-key',
|
|
186
|
+
* userId: 123,
|
|
187
|
+
* iterations: 100000
|
|
188
|
+
* });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
declare function deriveKeyFromConfig(config: {
|
|
192
|
+
secretKey: string;
|
|
193
|
+
userId?: string | number;
|
|
194
|
+
sessionId?: string;
|
|
195
|
+
iterations?: number;
|
|
196
|
+
keyPrefix?: string;
|
|
197
|
+
}): Promise<CryptoKey>;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* AES-256-GCM decryption using Web Crypto API.
|
|
201
|
+
*
|
|
202
|
+
* Decrypts data encrypted by Django-CFG backend.
|
|
203
|
+
*/
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Decrypt AES-256-GCM ciphertext.
|
|
207
|
+
*
|
|
208
|
+
* @param ciphertext - Encrypted data bytes
|
|
209
|
+
* @param key - CryptoKey for decryption
|
|
210
|
+
* @param iv - Initialization vector
|
|
211
|
+
* @param authTag - Authentication tag
|
|
212
|
+
* @returns Promise resolving to decrypted bytes
|
|
213
|
+
*/
|
|
214
|
+
declare function decryptAES256GCM(ciphertext: Uint8Array, key: CryptoKey, iv: Uint8Array, authTag: Uint8Array): Promise<Uint8Array>;
|
|
215
|
+
/**
|
|
216
|
+
* Decrypt a single encrypted field value.
|
|
217
|
+
*
|
|
218
|
+
* @param field - Encrypted field envelope
|
|
219
|
+
* @param key - CryptoKey for decryption
|
|
220
|
+
* @returns Promise resolving to decrypted value
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* const key = await deriveKeyFromConfig({ secretKey: '...' });
|
|
225
|
+
* const price = await decryptField(response.price, key);
|
|
226
|
+
* console.log(price); // 99.99
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
declare function decryptField<T = unknown>(field: EncryptedField, key: CryptoKey): Promise<T>;
|
|
230
|
+
/**
|
|
231
|
+
* Decrypt an entire encrypted response.
|
|
232
|
+
*
|
|
233
|
+
* @param response - Encrypted response envelope
|
|
234
|
+
* @param secretKey - Secret key for key derivation
|
|
235
|
+
* @param config - Additional config (userId, sessionId, etc.)
|
|
236
|
+
* @returns Promise resolving to decrypted response data
|
|
237
|
+
*/
|
|
238
|
+
declare function decryptResponse<T = unknown>(response: EncryptedResponse, secretKey: string, config?: Partial<Omit<DecryptionConfig, 'secretKey'>>): Promise<T>;
|
|
239
|
+
/**
|
|
240
|
+
* Recursively decrypt all encrypted fields in an object.
|
|
241
|
+
*
|
|
242
|
+
* @param data - Object potentially containing encrypted fields
|
|
243
|
+
* @param key - CryptoKey for decryption
|
|
244
|
+
* @returns Promise resolving to object with all fields decrypted
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```typescript
|
|
248
|
+
* const key = await deriveKeyFromConfig({ secretKey: '...' });
|
|
249
|
+
* const product = await decryptObject(response, key);
|
|
250
|
+
* // product.price is now decrypted
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare function decryptObject<T>(data: unknown, key: CryptoKey): Promise<T>;
|
|
254
|
+
/**
|
|
255
|
+
* Create a decryption client with pre-configured key.
|
|
256
|
+
*
|
|
257
|
+
* @param config - Decryption configuration
|
|
258
|
+
* @returns Object with decryption methods
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const crypto = await createDecryptionClient({
|
|
263
|
+
* secretKey: 'django-secret-key',
|
|
264
|
+
* userId: currentUser.id
|
|
265
|
+
* });
|
|
266
|
+
*
|
|
267
|
+
* const response = await fetch('/api/products/?encrypt=true');
|
|
268
|
+
* const data = await crypto.decryptObject(await response.json());
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
declare function createDecryptionClient(config: DecryptionConfig): Promise<{
|
|
272
|
+
/**
|
|
273
|
+
* Decrypt a single encrypted field.
|
|
274
|
+
*/
|
|
275
|
+
decryptField: <T = unknown>(field: EncryptedField) => Promise<T>;
|
|
276
|
+
/**
|
|
277
|
+
* Recursively decrypt all encrypted fields in an object.
|
|
278
|
+
*/
|
|
279
|
+
decryptObject: <T>(data: unknown) => Promise<T>;
|
|
280
|
+
/**
|
|
281
|
+
* Check if a value is an encrypted field.
|
|
282
|
+
*/
|
|
283
|
+
isEncryptedField: typeof isEncryptedField;
|
|
284
|
+
/**
|
|
285
|
+
* Check if a value is an encrypted response.
|
|
286
|
+
*/
|
|
287
|
+
isEncryptedResponse: typeof isEncryptedResponse;
|
|
288
|
+
}>;
|
|
289
|
+
/**
|
|
290
|
+
* Safe decryption wrapper that returns result or error.
|
|
291
|
+
*
|
|
292
|
+
* @param fn - Async function to execute
|
|
293
|
+
* @returns Promise resolving to DecryptionResult or DecryptionError
|
|
294
|
+
*/
|
|
295
|
+
declare function safeDecrypt<T>(fn: () => Promise<T>): Promise<DecryptionResult<T> | DecryptionError>;
|
|
296
|
+
|
|
297
|
+
export { type DecryptionConfig, type DecryptionError, type DecryptionResult, type EncryptedField, type EncryptedResponse, buildSalt, createDecryptionClient, decryptAES256GCM, decryptField, decryptObject, decryptResponse, deriveKey, deriveKeyBytes, deriveKeyFromConfig, isEncryptedField, isEncryptedResponse, safeDecrypt };
|