0
# Message Digests and HMAC
1
2
Cryptographic hash functions (MD5, SHA-1, SHA-256, SHA-512) and HMAC for message authentication. Node-forge provides pure JavaScript implementations of standard hash algorithms with consistent API patterns.
3
4
## Capabilities
5
6
### Message Digest Interface
7
8
All hash algorithms implement a consistent message digest interface.
9
10
```javascript { .api }
11
interface MessageDigest {
12
/** Algorithm name (e.g., 'md5', 'sha1', 'sha256', 'sha512') */
13
algorithm: string;
14
/** Block size in bytes for the algorithm */
15
blockLength: number;
16
/** Digest output length in bytes */
17
digestLength: number;
18
/** Current message length processed */
19
messageLength: number;
20
21
/**
22
* Start or restart the digest computation
23
* @returns This digest object for chaining
24
*/
25
start(): MessageDigest;
26
27
/**
28
* Update the digest with message data
29
* @param message - Data to hash as string
30
* @param encoding - Encoding format ('raw' or 'utf8', default: 'raw')
31
* @returns This digest object for chaining
32
*/
33
update(message: string, encoding?: 'raw' | 'utf8'): MessageDigest;
34
35
/**
36
* Complete the digest computation and return result
37
* @returns ByteStringBuffer containing the digest
38
*/
39
digest(): ByteStringBuffer;
40
}
41
```
42
43
### SHA-256 Hash Function
44
45
SHA-256 produces 256-bit (32-byte) hash values and is recommended for new applications.
46
47
```javascript { .api }
48
/**
49
* Create SHA-256 message digest
50
* @returns SHA-256 digest object
51
*/
52
forge.md.sha256.create(): MessageDigest;
53
54
// Also available as:
55
forge.sha256.create(): MessageDigest;
56
```
57
58
**Usage Examples:**
59
60
```javascript
61
const forge = require('node-forge');
62
63
// Basic SHA-256 hashing
64
const md = forge.md.sha256.create();
65
md.update('Hello World');
66
const hash = md.digest().toHex();
67
console.log('SHA-256:', hash);
68
69
// Chained operations
70
const hash2 = forge.md.sha256.create()
71
.update('Hello')
72
.update(' ')
73
.update('World')
74
.digest()
75
.toHex();
76
77
// Hash binary data
78
const binaryData = forge.util.hexToBytes('48656c6c6f');
79
const binaryHash = forge.md.sha256.create()
80
.update(binaryData)
81
.digest()
82
.toHex();
83
84
// Hash UTF-8 text
85
const utf8Hash = forge.md.sha256.create()
86
.update('Hello 世界', 'utf8')
87
.digest()
88
.toHex();
89
```
90
91
### SHA-1 Hash Function
92
93
SHA-1 produces 160-bit (20-byte) hash values. Consider SHA-256 for new applications.
94
95
```javascript { .api }
96
/**
97
* Create SHA-1 message digest
98
* @returns SHA-1 digest object
99
*/
100
forge.md.sha1.create(): MessageDigest;
101
102
// Also available as:
103
forge.sha1.create(): MessageDigest;
104
```
105
106
**Usage Examples:**
107
108
```javascript
109
// SHA-1 hashing
110
const sha1 = forge.md.sha1.create();
111
sha1.update('message to hash');
112
const sha1Hash = sha1.digest().toHex();
113
console.log('SHA-1:', sha1Hash);
114
```
115
116
### SHA-512 Hash Function
117
118
SHA-512 produces 512-bit (64-byte) hash values for high security applications.
119
120
```javascript { .api }
121
/**
122
* Create SHA-512 message digest
123
* @returns SHA-512 digest object
124
*/
125
forge.md.sha512.create(): MessageDigest;
126
127
// Also available as:
128
forge.sha512.create(): MessageDigest;
129
```
130
131
**Usage Examples:**
132
133
```javascript
134
// SHA-512 hashing
135
const sha512 = forge.md.sha512.create();
136
sha512.update('secure message');
137
const sha512Hash = sha512.digest().toHex();
138
console.log('SHA-512:', sha512Hash);
139
```
140
141
### SHA-384 Hash Function
142
143
SHA-384 produces 384-bit (48-byte) hash values as a truncated version of SHA-512.
144
145
```javascript { .api }
146
/**
147
* Create SHA-384 message digest
148
* @returns SHA-384 digest object
149
*/
150
forge.md.sha384.create(): MessageDigest;
151
152
// Also available as:
153
forge.sha384.create(): MessageDigest;
154
```
155
156
**Usage Examples:**
157
158
```javascript
159
// SHA-384 hashing
160
const sha384 = forge.md.sha384.create();
161
sha384.update('message for sha384');
162
const sha384Hash = sha384.digest().toHex();
163
console.log('SHA-384:', sha384Hash);
164
```
165
166
### MD5 Hash Function
167
168
MD5 produces 128-bit (16-byte) hash values. Use only for legacy compatibility.
169
170
```javascript { .api }
171
/**
172
* Create MD5 message digest
173
* @returns MD5 digest object
174
*/
175
forge.md.md5.create(): MessageDigest;
176
177
// Also available as:
178
forge.md5.create(): MessageDigest;
179
```
180
181
**Usage Examples:**
182
183
```javascript
184
// MD5 hashing (not recommended for security-critical applications)
185
const md5 = forge.md.md5.create();
186
md5.update('legacy data');
187
const md5Hash = md5.digest().toHex();
188
console.log('MD5:', md5Hash);
189
```
190
191
### HMAC (Hash-based Message Authentication Code)
192
193
HMAC provides message authentication using a secret key and a hash function.
194
195
```javascript { .api }
196
/**
197
* Create HMAC context
198
* @returns HMAC object for authentication
199
*/
200
forge.hmac.create(): HMACContext;
201
202
interface HMACContext {
203
/**
204
* Start HMAC with hash algorithm and key
205
* @param md - Hash algorithm name or MessageDigest object
206
* @param key - Secret key as string, bytes, or ByteStringBuffer
207
*/
208
start(md: string | MessageDigest, key: string | ByteStringBuffer): void;
209
210
/**
211
* Update HMAC with message data
212
* @param bytes - Message data to authenticate
213
*/
214
update(bytes: string): void;
215
216
/**
217
* Get the HMAC result
218
* @returns ByteStringBuffer containing the HMAC
219
*/
220
getMac(): ByteStringBuffer;
221
222
/**
223
* Get HMAC result as hex string
224
* @returns HMAC as hexadecimal string
225
*/
226
digest(): any;
227
}
228
```
229
230
**Usage Examples:**
231
232
```javascript
233
// HMAC-SHA256
234
const hmac = forge.hmac.create();
235
hmac.start('sha256', 'secret-key');
236
hmac.update('message to authenticate');
237
const mac = hmac.getMac().toHex();
238
console.log('HMAC-SHA256:', mac);
239
240
// HMAC with different algorithms
241
const hmacSha1 = forge.hmac.create();
242
hmacSha1.start('sha1', 'another-key');
243
hmacSha1.update('authenticated message');
244
const mac1 = hmacSha1.getMac().toHex();
245
246
// HMAC with MessageDigest object
247
const hmacCustom = forge.hmac.create();
248
hmacCustom.start(forge.md.sha512.create(), 'strong-key');
249
hmacCustom.update('high-security message');
250
const macCustom = hmacCustom.getMac().toHex();
251
252
// Key from bytes
253
const keyBytes = forge.random.getBytesSync(32); // 256-bit key
254
const hmacBytes = forge.hmac.create();
255
hmacBytes.start('sha256', keyBytes);
256
hmacBytes.update('message with random key');
257
const macBytes = hmacBytes.getMac().toHex();
258
```
259
260
### Hash Algorithm Registry
261
262
Access to the hash algorithm registry for dynamic algorithm selection.
263
264
```javascript { .api }
265
/**
266
* Registry of all message digest algorithms
267
*/
268
forge.md.algorithms: {
269
md5: () => MessageDigest;
270
sha1: () => MessageDigest;
271
sha256: () => MessageDigest;
272
sha384: () => MessageDigest;
273
sha512: () => MessageDigest;
274
};
275
```
276
277
**Usage Examples:**
278
279
```javascript
280
// Dynamic algorithm selection
281
function hashWithAlgorithm(message, algorithm) {
282
if (!(algorithm in forge.md.algorithms)) {
283
throw new Error(`Unsupported algorithm: ${algorithm}`);
284
}
285
286
const md = forge.md.algorithms[algorithm]();
287
md.update(message);
288
return md.digest().toHex();
289
}
290
291
const sha256Hash = hashWithAlgorithm('test', 'sha256');
292
const sha1Hash = hashWithAlgorithm('test', 'sha1');
293
```
294
295
### Hash Function Properties
296
297
Key properties of each hash algorithm for selection guidance.
298
299
```javascript { .api }
300
// Algorithm Properties
301
interface HashAlgorithmProperties {
302
MD5: {
303
digestLength: 16; // 128 bits
304
blockLength: 64; // 512 bits
305
security: 'broken'; // Cryptographically broken
306
};
307
SHA1: {
308
digestLength: 20; // 160 bits
309
blockLength: 64; // 512 bits
310
security: 'weak'; // Collision attacks exist
311
};
312
SHA256: {
313
digestLength: 32; // 256 bits
314
blockLength: 64; // 512 bits
315
security: 'strong'; // Currently secure
316
};
317
SHA384: {
318
digestLength: 48; // 384 bits
319
blockLength: 128; // 1024 bits
320
security: 'strong'; // Currently secure
321
};
322
SHA512: {
323
digestLength: 64; // 512 bits
324
blockLength: 128; // 1024 bits
325
security: 'strong'; // Currently secure
326
};
327
}
328
```
329
330
### Performance Considerations
331
332
Optimize hash operations for different use cases.
333
334
**Usage Examples:**
335
336
```javascript
337
// Efficient hashing of large data
338
function hashLargeData(dataChunks) {
339
const md = forge.md.sha256.create();
340
341
for (const chunk of dataChunks) {
342
md.update(chunk);
343
}
344
345
return md.digest().toHex();
346
}
347
348
// Streaming hash computation
349
function createStreamingHasher(algorithm = 'sha256') {
350
const md = forge.md[algorithm].create();
351
352
return {
353
update: (data) => md.update(data),
354
finalize: () => md.digest().toHex(),
355
reset: () => md.start()
356
};
357
}
358
359
const hasher = createStreamingHasher('sha256');
360
hasher.update('chunk 1');
361
hasher.update('chunk 2');
362
const result = hasher.finalize();
363
```
364
365
### Security Best Practices
366
367
Guidelines for secure hash function usage.
368
369
```javascript
370
// Recommended algorithms for different use cases
371
const RECOMMENDED_ALGORITHMS = {
372
// For general purpose hashing
373
general: 'sha256',
374
375
// For password hashing (use PBKDF2 or bcrypt instead)
376
passwords: 'DO_NOT_USE_PLAIN_HASH',
377
378
// For digital signatures
379
signatures: 'sha256', // or 'sha512'
380
381
// For HMAC
382
hmac: 'sha256',
383
384
// For integrity checking
385
integrity: 'sha256'
386
};
387
388
// Secure HMAC key generation
389
const hmacKey = forge.random.getBytesSync(32); // 256-bit key
390
const hmac = forge.hmac.create();
391
hmac.start('sha256', hmacKey);
392
393
// Constant-time HMAC verification (approximate)
394
function verifyHMAC(message, key, expectedMac) {
395
const hmac = forge.hmac.create();
396
hmac.start('sha256', key);
397
hmac.update(message);
398
const computedMac = hmac.getMac().toHex();
399
400
// Note: This is not truly constant-time in JavaScript
401
// For production, use a dedicated constant-time comparison library
402
return computedMac === expectedMac;
403
}
404
```
405
406
### Error Handling
407
408
Handle common errors in hash operations.
409
410
```javascript
411
try {
412
const md = forge.md.sha256.create();
413
md.update(message);
414
const hash = md.digest().toHex();
415
416
} catch (error) {
417
// Handle errors:
418
// - Invalid encoding specified
419
// - Memory allocation failures for very large inputs
420
// - Invalid algorithm names for HMAC
421
console.error('Hashing failed:', error.message);
422
}
423
424
// HMAC error handling
425
try {
426
const hmac = forge.hmac.create();
427
hmac.start('invalid-algorithm', 'key'); // Will throw error
428
429
} catch (error) {
430
console.error('HMAC initialization failed:', error.message);
431
}
432
```