0
# PKCS Standards
1
2
Implementation of PKCS standards including PKCS#1 (RSA), PKCS#7 (CMS), and PKCS#12 (key stores). Node-forge provides comprehensive support for standard cryptographic data formats used in PKI systems.
3
4
## Capabilities
5
6
### PKCS#1 - RSA Cryptography Standard
7
8
PKCS#1 defines RSA encryption and signature schemes with proper padding.
9
10
```javascript { .api }
11
/**
12
* PKCS#1 padding schemes and operations
13
*/
14
forge.pkcs1 = {
15
/**
16
* Encode message using PKCS#1 v1.5 padding
17
* @param m - Message to encode
18
* @param key - RSA key for size calculation
19
* @param bt - Block type (0x00, 0x01, 0x02)
20
* @returns Padded message
21
*/
22
encode_rsa_oaep: (key: any, message: string, options?: any) => string;
23
24
/**
25
* Decode PKCS#1 v1.5 padded message
26
* @param m - Padded message
27
* @param key - RSA key
28
* @param pub - True for public key operation
29
* @returns Original message
30
*/
31
decode_rsa_oaep: (key: any, em: string, options?: any) => string;
32
};
33
```
34
35
**Usage Examples:**
36
37
```javascript
38
const forge = require('node-forge');
39
40
// RSA-OAEP encryption (handled automatically by RSA encrypt/decrypt)
41
const keypair = forge.pki.rsa.generateKeyPair(2048);
42
const message = 'Secret message';
43
44
// OAEP padding is applied automatically
45
const encrypted = keypair.publicKey.encrypt(message, 'RSA-OAEP');
46
const decrypted = keypair.privateKey.decrypt(encrypted, 'RSA-OAEP');
47
```
48
49
### PKCS#7 - Cryptographic Message Syntax
50
51
PKCS#7 provides formats for signed, encrypted, and authenticated data.
52
53
```javascript { .api }
54
/**
55
* Create PKCS#7 signed data structure
56
* @returns PKCS#7 signed data object
57
*/
58
forge.pkcs7.createSignedData(): PKCS7SignedData;
59
60
/**
61
* Create PKCS#7 encrypted data structure
62
* @returns PKCS#7 encrypted data object
63
*/
64
forge.pkcs7.createEncryptedData(): PKCS7EncryptedData;
65
66
/**
67
* Create PKCS#7 enveloped data structure
68
* @returns PKCS#7 enveloped data object
69
*/
70
forge.pkcs7.createEnvelopedData(): PKCS7EnvelopedData;
71
72
/**
73
* Parse PKCS#7 message from PEM format
74
* @param pem - PEM-encoded PKCS#7 message
75
* @returns PKCS#7 message object
76
*/
77
forge.pkcs7.messageFromPem(pem: string): PKCS7Message;
78
79
/**
80
* Convert PKCS#7 message to PEM format
81
* @param msg - PKCS#7 message object
82
* @param maxline - Maximum line length
83
* @returns PEM-encoded PKCS#7 message
84
*/
85
forge.pkcs7.messageToPem(msg: PKCS7Message, maxline?: number): string;
86
87
/**
88
* Parse PKCS#7 message from ASN.1
89
* @param asn1 - ASN.1 object
90
* @returns PKCS#7 message object
91
*/
92
forge.pkcs7.messageFromAsn1(asn1: ASN1): PKCS7Message;
93
94
interface PKCS7SignedData {
95
/** Content type OID */
96
type: string;
97
/** Content to be signed */
98
content: any;
99
/** Certificates included in the message */
100
certificates: Certificate[];
101
/** Certificate revocation lists */
102
crls: any[];
103
/** Signer information */
104
signers: PKCS7Signer[];
105
106
/**
107
* Add certificate to the signed data
108
* @param cert - Certificate to add
109
*/
110
addCertificate(cert: Certificate | string): void;
111
112
/**
113
* Add signer to the signed data
114
* @param signer - Signer information
115
*/
116
addSigner(signer: PKCS7Signer): void;
117
118
/**
119
* Sign the data
120
* @param key - Private key for signing
121
* @param authenticatedAttributes - Additional attributes to sign
122
*/
123
sign(key?: PrivateKey, authenticatedAttributes?: any[]): void;
124
125
/**
126
* Verify all signatures
127
* @param caStore - Certificate store for verification
128
* @returns True if all signatures are valid
129
*/
130
verify(caStore?: CertificateStore): boolean;
131
}
132
133
interface PKCS7Signer {
134
/** Signer's certificate */
135
certificate: Certificate;
136
/** Signature algorithm */
137
digestAlgorithm: string;
138
/** Authentication attributes */
139
authenticatedAttributes: any[];
140
/** Unauthenticated attributes */
141
unauthenticatedAttributes: any[];
142
/** Digital signature */
143
signature: string;
144
}
145
```
146
147
**Usage Examples:**
148
149
```javascript
150
// Create signed data
151
const p7 = forge.pkcs7.createSignedData();
152
153
// Set content to sign
154
p7.content = forge.util.createBuffer('Hello, World!', 'utf8');
155
156
// Add certificate
157
p7.addCertificate(signerCert);
158
159
// Add signer
160
p7.addSigner({
161
key: signerPrivateKey,
162
certificate: signerCert,
163
digestAlgorithm: forge.pki.oids.sha256,
164
authenticatedAttributes: [{
165
type: forge.pki.oids.contentTypes,
166
value: forge.pki.oids.data
167
}, {
168
type: forge.pki.oids.messageDigest
169
}, {
170
type: forge.pki.oids.signingTime,
171
value: new Date()
172
}]
173
});
174
175
// Sign the data
176
p7.sign();
177
178
// Convert to PEM
179
const pem = forge.pkcs7.messageToPem(p7);
180
181
// Verify signature
182
const caStore = forge.pki.createCertificateStore([caCert]);
183
const verified = p7.verify(caStore);
184
console.log('Signature verified:', verified);
185
```
186
187
### PKCS#12 - Personal Information Exchange
188
189
PKCS#12 provides a format for storing private keys and certificates.
190
191
```javascript { .api }
192
/**
193
* Convert key and certificate to PKCS#12 format
194
* @param key - Private key
195
* @param cert - Certificate
196
* @param password - Protection password
197
* @param options - Additional options
198
* @returns PKCS#12 ASN.1 structure
199
*/
200
forge.pkcs12.toPkcs12Asn1(
201
key: PrivateKey,
202
cert: Certificate,
203
password: string,
204
options?: PKCS12Options
205
): ASN1;
206
207
/**
208
* Convert PKCS#12 ASN.1 to PEM format
209
* @param asn1 - PKCS#12 ASN.1 structure
210
* @param maxline - Maximum line length
211
* @returns PEM-encoded PKCS#12
212
*/
213
forge.pkcs12.toPem(asn1: ASN1, maxline?: number): string;
214
215
/**
216
* Parse PKCS#12 from ASN.1
217
* @param asn1 - PKCS#12 ASN.1 structure
218
* @param password - Protection password
219
* @returns PKCS#12 parsed data
220
*/
221
forge.pkcs12.pkcs12FromAsn1(asn1: ASN1, password?: string): PKCS12;
222
223
/**
224
* Parse PKCS#12 from DER bytes
225
* @param bytes - DER-encoded PKCS#12 data
226
* @param password - Protection password
227
* @returns PKCS#12 parsed data
228
*/
229
forge.pkcs12.pkcs12FromDer(bytes: string, password?: string): PKCS12;
230
231
interface PKCS12Options {
232
/** Encryption algorithm for private key */
233
algorithm?: string;
234
/** Key derivation iteration count */
235
count?: number;
236
/** Salt length */
237
saltSize?: number;
238
/** Use legacy algorithms */
239
useMac?: boolean;
240
/** MAC iteration count */
241
macCount?: number;
242
/** Friendly name for certificate */
243
friendlyName?: string;
244
/** Generate local key ID */
245
generateLocalKeyId?: boolean;
246
}
247
248
interface PKCS12 {
249
/** PKCS#12 version */
250
version: string;
251
/** Authentication safe bags */
252
safeContents: SafeBag[];
253
/** MAC data for integrity */
254
macData?: any;
255
256
/**
257
* Get certificate from PKCS#12
258
* @param bagId - Bag identifier
259
* @returns Certificate or null
260
*/
261
getBagsByFriendlyName(name: string, bagType: string): SafeBag[];
262
263
/**
264
* Get private key from PKCS#12
265
* @param bagId - Bag identifier
266
* @returns Private key or null
267
*/
268
getBagsByLocalKeyId(keyId: string, bagType: string): SafeBag[];
269
}
270
271
interface SafeBag {
272
/** Bag type */
273
type: string;
274
/** Bag attributes */
275
attributes: any;
276
/** Bag value (key, certificate, etc.) */
277
key?: PrivateKey;
278
cert?: Certificate;
279
asn1?: ASN1;
280
}
281
```
282
283
**Usage Examples:**
284
285
```javascript
286
// Create PKCS#12 from key and certificate
287
const p12Asn1 = forge.pkcs12.toPkcs12Asn1(
288
privateKey,
289
certificate,
290
'password123',
291
{
292
algorithm: '3des', // or 'aes128', 'aes192', 'aes256'
293
count: 100000, // PBKDF2 iterations
294
saltSize: 8, // Salt size in bytes
295
useMac: true, // Include MAC for integrity
296
friendlyName: 'My Certificate'
297
}
298
);
299
300
// Convert to PEM format
301
const p12Pem = forge.pkcs12.toPem(p12Asn1);
302
303
// Save as binary (for .p12/.pfx files)
304
const p12Der = forge.asn1.toDer(p12Asn1).getBytes();
305
306
// Parse PKCS#12 file
307
const p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, 'password123');
308
309
// Extract certificates and keys
310
const certBags = p12.getBagsByFriendlyName('My Certificate', forge.pki.oids.certBag);
311
const keyBags = p12.getBagsByFriendlyName('My Certificate', forge.pki.oids.pkcs8ShroudedKeyBag);
312
313
if (certBags.length > 0) {
314
const cert = certBags[0].cert;
315
console.log('Certificate:', cert);
316
}
317
318
if (keyBags.length > 0) {
319
const key = keyBags[0].key;
320
console.log('Private key:', key);
321
}
322
```
323
324
### PBKDF2 - Password-Based Key Derivation
325
326
PBKDF2 derives cryptographic keys from passwords with salt and iteration count.
327
328
```javascript { .api }
329
/**
330
* Derive key using PBKDF2
331
* @param password - Password string
332
* @param salt - Salt bytes
333
* @param iterations - Iteration count
334
* @param keyLength - Desired key length in bytes
335
* @param md - Message digest algorithm (default: SHA-1)
336
* @returns Derived key as binary string
337
*/
338
forge.pkcs5.pbkdf2(
339
password: string,
340
salt: string | ByteStringBuffer,
341
iterations: number,
342
keyLength: number,
343
md?: MessageDigest | string
344
): string;
345
```
346
347
**Usage Examples:**
348
349
```javascript
350
// Derive encryption key from password
351
const password = 'user-password';
352
const salt = forge.random.getBytesSync(16); // 128-bit salt
353
const iterations = 100000; // OWASP recommended minimum
354
const keyLength = 32; // 256-bit key
355
356
const derivedKey = forge.pkcs5.pbkdf2(password, salt, iterations, keyLength, 'sha256');
357
358
// Use derived key for encryption
359
const cipher = forge.cipher.createCipher('AES-CBC', derivedKey);
360
const iv = forge.random.getBytesSync(16);
361
cipher.start({iv: iv});
362
cipher.update(forge.util.createBuffer('secret data'));
363
cipher.finish();
364
const encrypted = cipher.output.getBytes();
365
366
// Store salt, iterations, IV, and encrypted data for later decryption
367
const keyDerivationInfo = {
368
salt: forge.util.encode64(salt),
369
iterations: iterations,
370
algorithm: 'sha256',
371
keyLength: keyLength
372
};
373
```
374
375
### Password-Based Encryption (PBE)
376
377
Password-based encryption schemes for protecting private keys.
378
379
```javascript { .api }
380
/**
381
* Available PBE algorithms
382
*/
383
forge.pbe.algorithms = {
384
'pbeWithMD2AndDES-CBC': any;
385
'pbeWithMD5AndDES-CBC': any;
386
'pbeWithMD2AndRC2-CBC': any;
387
'pbeWithMD5AndRC2-CBC': any;
388
'pbeWithSHA1AndDES-CBC': any;
389
'pbeWithSHA1AndRC2-CBC': any;
390
'pbeWithSHA1And3-KeyTripleDES-CBC': any;
391
'pbeWithSHA1And2-KeyTripleDES-CBC': any;
392
'pbeWithSHA1And128BitRC2-CBC': any;
393
'pbeWithSHA1And40BitRC2-CBC': any;
394
};
395
396
/**
397
* Encrypt data using password-based encryption
398
* @param data - Data to encrypt
399
* @param password - Password for encryption
400
* @param algorithm - PBE algorithm
401
* @param options - Encryption options
402
* @returns Encrypted data
403
*/
404
forge.pbe.encrypt(data: any, password: string, algorithm: string, options?: any): any;
405
406
/**
407
* Decrypt PBE-encrypted data
408
* @param encryptedData - Encrypted data
409
* @param password - Password for decryption
410
* @returns Decrypted data
411
*/
412
forge.pbe.decrypt(encryptedData: any, password: string): any;
413
```
414
415
**Usage Examples:**
416
417
```javascript
418
// Encrypt private key with password-based encryption
419
const privateKeyInfo = forge.pki.wrapRsaPrivateKey(privateKey);
420
const encryptedPrivateKeyInfo = forge.pbe.encrypt(
421
privateKeyInfo,
422
'encryption-password',
423
'pbeWithSHA1And3-KeyTripleDES-CBC'
424
);
425
426
// Decrypt private key
427
const decryptedPrivateKeyInfo = forge.pbe.decrypt(
428
encryptedPrivateKeyInfo,
429
'encryption-password'
430
);
431
const restoredPrivateKey = forge.pki.privateKeyFromAsn1(decryptedPrivateKeyInfo);
432
```
433
434
### Error Handling
435
436
Handle common PKCS operation errors.
437
438
```javascript
439
try {
440
// PKCS#7 operations
441
const p7 = forge.pkcs7.createSignedData();
442
p7.sign(privateKey);
443
444
// PKCS#12 operations
445
const p12 = forge.pkcs12.toPkcs12Asn1(privateKey, certificate, password);
446
447
// PBKDF2 key derivation
448
const key = forge.pkcs5.pbkdf2(password, salt, iterations, keyLength);
449
450
} catch (error) {
451
// Handle errors:
452
// - Invalid passwords for PKCS#12
453
// - Missing certificates or keys
454
// - Unsupported algorithms
455
// - Malformed PKCS structures
456
// - Signature verification failures
457
// - Key derivation failures
458
console.error('PKCS operation failed:', error.message);
459
}
460
```