0
# Random Number Generation
1
2
Secure random number generation for cryptographic operations including key generation and IV creation. Node-forge provides cross-platform secure random number generation with multiple entropy sources and PRNG implementations.
3
4
## Capabilities
5
6
### Basic Random Number Generation
7
8
Generate cryptographically secure random bytes for keys, IVs, and salts.
9
10
```javascript { .api }
11
/**
12
* Generate random bytes synchronously
13
* @param count - Number of bytes to generate
14
* @returns Random bytes as binary string
15
*/
16
forge.random.getBytesSync(count: number): string;
17
18
/**
19
* Generate random bytes asynchronously
20
* @param count - Number of bytes to generate
21
* @param callback - Callback function to receive bytes
22
*/
23
forge.random.getBytes(count: number, callback?: (err: Error | null, bytes: string) => void): string | void;
24
```
25
26
**Usage Examples:**
27
28
```javascript
29
const forge = require('node-forge');
30
31
// Generate random key material
32
const aesKey = forge.random.getBytesSync(32); // 256-bit AES key
33
const iv = forge.random.getBytesSync(16); // 128-bit IV
34
const salt = forge.random.getBytesSync(16); // 128-bit salt
35
36
console.log('AES Key (hex):', forge.util.bytesToHex(aesKey));
37
console.log('IV (hex):', forge.util.bytesToHex(iv));
38
console.log('Salt (hex):', forge.util.bytesToHex(salt));
39
40
// Asynchronous generation (for non-blocking operation)
41
forge.random.getBytes(32, (err, bytes) => {
42
if (err) {
43
console.error('Random generation failed:', err);
44
return;
45
}
46
console.log('Async random bytes:', forge.util.bytesToHex(bytes));
47
});
48
49
// Generate multiple random values
50
const sessionId = forge.random.getBytesSync(16);
51
const nonce = forge.random.getBytesSync(12); // 96-bit nonce for GCM
52
const challenge = forge.random.getBytesSync(32); // Random challenge
53
```
54
55
### PRNG (Pseudo-Random Number Generator)
56
57
Create and manage pseudo-random number generator instances with custom seeds.
58
59
```javascript { .api }
60
/**
61
* Create PRNG instance
62
* @param plugin - PRNG plugin/algorithm
63
* @returns PRNG context
64
*/
65
forge.prng.create(plugin: any): PRNGContext;
66
67
/**
68
* Create random number generator instance
69
* @returns Random generator instance
70
*/
71
forge.random.createInstance(): RandomGenerator;
72
73
interface PRNGContext {
74
/** PRNG plugin */
75
plugin: any;
76
/** Internal state */
77
key: any;
78
/** Seed the PRNG */
79
seed: string;
80
81
/**
82
* Generate random bytes
83
* @param count - Number of bytes
84
* @returns Random bytes
85
*/
86
generate(count: number): string;
87
}
88
89
interface RandomGenerator {
90
/**
91
* Generate random bytes synchronously
92
* @param count - Number of bytes
93
* @returns Random bytes as binary string
94
*/
95
getBytesSync(count: number): string;
96
97
/**
98
* Generate random bytes asynchronously
99
* @param count - Number of bytes
100
* @param callback - Callback for result
101
*/
102
getBytes(count: number, callback: (err: Error | null, bytes: string) => void): void;
103
104
/**
105
* Seed the random generator
106
* @param seed - Seed data
107
*/
108
seedFileSync(seed: string): void;
109
}
110
```
111
112
**Usage Examples:**
113
114
```javascript
115
// Create custom random generator instance
116
const rng = forge.random.createInstance();
117
118
// Seed with custom entropy
119
const customSeed = forge.util.encodeUtf8('custom-entropy-source') +
120
Date.now().toString() +
121
Math.random().toString();
122
rng.seedFileSync(customSeed);
123
124
// Generate random bytes with custom instance
125
const customRandom = rng.getBytesSync(32);
126
console.log('Custom random:', forge.util.bytesToHex(customRandom));
127
128
// Asynchronous generation with custom instance
129
rng.getBytes(16, (err, bytes) => {
130
if (!err) {
131
console.log('Custom async random:', forge.util.bytesToHex(bytes));
132
}
133
});
134
```
135
136
### Entropy Collection
137
138
Methods for collecting entropy from various sources to seed random generators.
139
140
```javascript { .api }
141
/**
142
* Collect entropy from browser/environment
143
* @param callback - Callback with collected entropy
144
*/
145
forge.random.collect(callback: (bytes: string) => void): void;
146
147
/**
148
* Register entropy collector
149
* @param collector - Collector function
150
*/
151
forge.random.registerCollector(collector: () => string): void;
152
153
/**
154
* Start collecting entropy continuously
155
*/
156
forge.random.startCollecting(): void;
157
158
/**
159
* Stop collecting entropy
160
*/
161
forge.random.stopCollecting(): void;
162
```
163
164
**Usage Examples:**
165
166
```javascript
167
// Collect additional entropy (browser environment)
168
if (typeof window !== 'undefined') {
169
forge.random.collect((bytes) => {
170
console.log('Collected entropy:', bytes.length, 'bytes');
171
});
172
173
// Register custom entropy collector
174
forge.random.registerCollector(() => {
175
return Date.now().toString() +
176
navigator.userAgent +
177
Math.random().toString() +
178
(performance.now ? performance.now().toString() : '');
179
});
180
181
// Start continuous entropy collection
182
forge.random.startCollecting();
183
}
184
185
// Node.js entropy collection
186
if (typeof process !== 'undefined') {
187
const crypto = require('crypto');
188
189
// Register Node.js crypto as entropy source
190
forge.random.registerCollector(() => {
191
return crypto.randomBytes(32).toString('binary');
192
});
193
}
194
```
195
196
### Random Number Utilities
197
198
Utility functions for working with random data in different formats.
199
200
```javascript { .api }
201
/**
202
* Generate random integer in range
203
* @param min - Minimum value (inclusive)
204
* @param max - Maximum value (exclusive)
205
* @returns Random integer
206
*/
207
function randomInt(min: number, max: number): number;
208
209
/**
210
* Generate random hex string
211
* @param length - Length in bytes
212
* @returns Random hex string
213
*/
214
function randomHex(length: number): string;
215
216
/**
217
* Generate random base64 string
218
* @param length - Length in bytes
219
* @returns Random base64 string
220
*/
221
function randomBase64(length: number): string;
222
223
/**
224
* Shuffle array randomly
225
* @param array - Array to shuffle
226
* @returns Shuffled array
227
*/
228
function shuffleArray<T>(array: T[]): T[];
229
```
230
231
**Usage Examples:**
232
233
```javascript
234
// Utility functions for random data
235
function randomInt(min, max) {
236
const range = max - min;
237
const bytes = forge.random.getBytesSync(4);
238
const value = forge.util.createBuffer(bytes).getInt32();
239
return min + Math.abs(value) % range;
240
}
241
242
function randomHex(length) {
243
const bytes = forge.random.getBytesSync(length);
244
return forge.util.bytesToHex(bytes);
245
}
246
247
function randomBase64(length) {
248
const bytes = forge.random.getBytesSync(length);
249
return forge.util.encode64(bytes);
250
}
251
252
function shuffleArray(array) {
253
const shuffled = [...array];
254
for (let i = shuffled.length - 1; i > 0; i--) {
255
const j = randomInt(0, i + 1);
256
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
257
}
258
return shuffled;
259
}
260
261
// Usage examples
262
const randomId = randomHex(16); // 32-character hex ID
263
const sessionToken = randomBase64(24); // Base64 session token
264
const randomPort = randomInt(8000, 9000); // Random port number
265
const shuffledItems = shuffleArray(['a', 'b', 'c', 'd', 'e']);
266
```
267
268
### Secure Random Practices
269
270
Best practices for secure random number generation in different scenarios.
271
272
**Key Generation:**
273
274
```javascript
275
// Generate cryptographic keys with proper lengths
276
const keys = {
277
aes128: forge.random.getBytesSync(16), // 128-bit AES
278
aes192: forge.random.getBytesSync(24), // 192-bit AES
279
aes256: forge.random.getBytesSync(32), // 256-bit AES
280
hmacKey: forge.random.getBytesSync(32), // 256-bit HMAC key
281
salt: forge.random.getBytesSync(16) // 128-bit salt (minimum)
282
};
283
284
// Generate IVs for different algorithms
285
const ivs = {
286
aes_cbc: forge.random.getBytesSync(16), // 128-bit IV for AES-CBC
287
aes_gcm: forge.random.getBytesSync(12), // 96-bit IV for AES-GCM (recommended)
288
des: forge.random.getBytesSync(8) // 64-bit IV for DES
289
};
290
```
291
292
**Session Management:**
293
294
```javascript
295
// Generate secure session identifiers
296
function generateSessionId() {
297
return forge.util.encode64(forge.random.getBytesSync(32))
298
.replace(/\+/g, '-')
299
.replace(/\//g, '_')
300
.replace(/=/g, ''); // URL-safe base64
301
}
302
303
// Generate CSRF tokens
304
function generateCSRFToken() {
305
return forge.util.bytesToHex(forge.random.getBytesSync(32));
306
}
307
308
// Generate API keys
309
function generateAPIKey() {
310
const timestamp = Date.now().toString(16);
311
const randomPart = forge.util.bytesToHex(forge.random.getBytesSync(16));
312
return `ak_${timestamp}_${randomPart}`;
313
}
314
```
315
316
**Nonces and Challenges:**
317
318
```javascript
319
// Generate cryptographic nonces
320
function generateNonce(length = 16) {
321
return forge.random.getBytesSync(length);
322
}
323
324
// Generate challenge-response values
325
function generateChallenge() {
326
return {
327
challenge: forge.util.encode64(forge.random.getBytesSync(32)),
328
timestamp: Date.now(),
329
expires: Date.now() + 300000 // 5 minutes
330
};
331
}
332
```
333
334
### Performance Considerations
335
336
Optimize random number generation for different use cases.
337
338
**Batch Generation:**
339
340
```javascript
341
// Generate multiple random values efficiently
342
function generateBatch(count, size) {
343
const totalBytes = count * size;
344
const allBytes = forge.random.getBytesSync(totalBytes);
345
const results = [];
346
347
for (let i = 0; i < count; i++) {
348
const start = i * size;
349
const end = start + size;
350
results.push(allBytes.slice(start, end));
351
}
352
353
return results;
354
}
355
356
// Generate multiple keys at once
357
const keyBatch = generateBatch(10, 32); // 10 AES-256 keys
358
const ivBatch = generateBatch(10, 16); // 10 AES IVs
359
```
360
361
**Caching for High-Frequency Use:**
362
363
```javascript
364
// Random pool for high-frequency operations
365
class RandomPool {
366
constructor(poolSize = 1024) {
367
this.pool = forge.random.getBytesSync(poolSize);
368
this.position = 0;
369
this.poolSize = poolSize;
370
}
371
372
getBytes(count) {
373
if (this.position + count > this.poolSize) {
374
// Refill pool
375
this.pool = forge.random.getBytesSync(this.poolSize);
376
this.position = 0;
377
}
378
379
const result = this.pool.slice(this.position, this.position + count);
380
this.position += count;
381
return result;
382
}
383
}
384
385
const randomPool = new RandomPool();
386
// Use pool for frequent small random values
387
const quickRandom = randomPool.getBytes(16);
388
```
389
390
### Error Handling
391
392
Handle random generation failures and entropy issues.
393
394
```javascript
395
try {
396
// Basic random generation
397
const randomBytes = forge.random.getBytesSync(32);
398
399
// Async generation with error handling
400
forge.random.getBytes(32, (err, bytes) => {
401
if (err) {
402
console.error('Async random generation failed:', err);
403
// Fallback to sync generation
404
const fallbackBytes = forge.random.getBytesSync(32);
405
// Use fallbackBytes...
406
return;
407
}
408
// Use bytes...
409
});
410
411
} catch (error) {
412
// Handle errors:
413
// - Insufficient entropy
414
// - PRNG initialization failures
415
// - Platform-specific random source failures
416
console.error('Random generation failed:', error.message);
417
418
// Implement fallback strategy
419
console.warn('Using fallback random generation');
420
const fallback = Date.now().toString() + Math.random().toString();
421
const hashedFallback = forge.md.sha256.create()
422
.update(fallback)
423
.digest()
424
.getBytes();
425
}
426
427
// Check for secure random availability
428
function isSecureRandomAvailable() {
429
try {
430
forge.random.getBytesSync(1);
431
return true;
432
} catch (error) {
433
return false;
434
}
435
}
436
437
if (!isSecureRandomAvailable()) {
438
console.warn('Secure random generation not available');
439
// Implement alternative strategy or warn user
440
}
441
```