0
# Public Key Infrastructure
1
2
Certificate management, PEM/DER conversion, and X.509 certificate creation and validation. Node-forge provides comprehensive PKI functionality for working with certificates, certificate authorities, and public/private key formats.
3
4
## Capabilities
5
6
### Certificate Creation
7
8
Create new X.509 certificates with full control over all certificate fields.
9
10
```javascript { .api }
11
/**
12
* Create a new empty X.509 certificate
13
* @returns Certificate object ready for configuration
14
*/
15
forge.pki.createCertificate(): Certificate;
16
17
interface Certificate {
18
/** Certificate version (typically 0x02 for v3) */
19
version: number;
20
/** Serial number as hex string */
21
serialNumber: string;
22
/** Signature algorithm OID */
23
signatureOid: string | null;
24
/** Certificate signature */
25
signature: string | null;
26
/** Signature algorithm information */
27
siginfo: {
28
algorithmOid: string | null;
29
};
30
/** Certificate validity period */
31
validity: {
32
notBefore: Date;
33
notAfter: Date;
34
};
35
/** Certificate issuer (CA) information */
36
issuer: CertificateSubject;
37
/** Certificate subject information */
38
subject: CertificateSubject;
39
/** Certificate extensions array */
40
extensions: CertificateExtension[];
41
/** Public key associated with certificate */
42
publicKey: PublicKey;
43
/** Message digest used for signing */
44
md: MessageDigest | null;
45
46
/**
47
* Set certificate subject
48
* @param attrs - Array of subject attributes
49
* @param uniqueId - Optional unique identifier
50
*/
51
setSubject(attrs: SubjectAttribute[], uniqueId?: string): void;
52
53
/**
54
* Set certificate issuer
55
* @param attrs - Array of issuer attributes
56
* @param uniqueId - Optional unique identifier
57
*/
58
setIssuer(attrs: SubjectAttribute[], uniqueId?: string): void;
59
60
/**
61
* Set certificate extensions
62
* @param exts - Array of extensions
63
*/
64
setExtensions(exts: CertificateExtension[]): void;
65
66
/**
67
* Sign the certificate with a private key
68
* @param privateKey - Private key for signing
69
* @param md - Message digest to use (default: SHA-256)
70
*/
71
sign(privateKey: PrivateKey, md?: MessageDigest): void;
72
73
/**
74
* Verify certificate signature against a CA store
75
* @param caStore - Array of trusted CA certificates
76
* @returns True if certificate is valid
77
*/
78
verify(caStore: Certificate[]): boolean;
79
}
80
81
interface CertificateSubject {
82
/** Subject/issuer attributes */
83
attributes: SubjectAttribute[];
84
/** Subject/issuer hash */
85
hash: string | null;
86
87
/**
88
* Get attribute by short name
89
* @param sn - Short name (e.g., 'CN', 'O', 'OU')
90
* @returns Attribute object or null
91
*/
92
getField(sn: string): SubjectAttribute | null;
93
94
/**
95
* Add new attribute
96
* @param attr - Attribute to add
97
*/
98
addField(attr: SubjectAttribute): void;
99
}
100
101
interface SubjectAttribute {
102
/** Attribute name */
103
name: string;
104
/** Attribute short name */
105
shortName?: string;
106
/** Attribute value */
107
value: string;
108
/** Attribute type (for custom attributes) */
109
type?: string;
110
}
111
```
112
113
**Usage Examples:**
114
115
```javascript
116
const forge = require('node-forge');
117
118
// Generate key pair for certificate
119
const keypair = forge.pki.rsa.generateKeyPair(2048);
120
121
// Create certificate
122
const cert = forge.pki.createCertificate();
123
cert.publicKey = keypair.publicKey;
124
cert.serialNumber = '01';
125
cert.validity.notBefore = new Date();
126
cert.validity.notAfter = new Date();
127
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
128
129
// Set subject (entity the certificate represents)
130
cert.subject.attributes.push({
131
name: 'commonName',
132
value: 'example.com'
133
}, {
134
name: 'countryName',
135
value: 'US'
136
}, {
137
shortName: 'ST',
138
value: 'Virginia'
139
}, {
140
name: 'localityName',
141
value: 'Blacksburg'
142
}, {
143
name: 'organizationName',
144
value: 'Test'
145
}, {
146
shortName: 'OU',
147
value: 'Test'
148
});
149
150
// Set issuer (self-signed)
151
cert.issuer.attributes = cert.subject.attributes;
152
153
// Sign certificate
154
cert.sign(keypair.privateKey, forge.md.sha256.create());
155
```
156
157
### PEM Format Conversion
158
159
Convert between PEM text format and JavaScript objects for certificates and keys.
160
161
```javascript { .api }
162
/**
163
* Convert certificate from PEM format
164
* @param pem - PEM-encoded certificate string
165
* @param computeHash - Whether to compute subject/issuer hashes
166
* @param strict - Strict parsing mode
167
* @returns Certificate object
168
*/
169
forge.pki.certificateFromPem(pem: string, computeHash?: boolean, strict?: boolean): Certificate;
170
171
/**
172
* Convert certificate to PEM format
173
* @param certificate - Certificate object to convert
174
* @param maxline - Maximum line length for PEM output
175
* @returns PEM-encoded certificate string
176
*/
177
forge.pki.certificateToPem(certificate: Certificate, maxline?: number): string;
178
179
/**
180
* Convert private key from PEM format
181
* @param pem - PEM-encoded private key string
182
* @returns Private key object
183
*/
184
forge.pki.privateKeyFromPem(pem: string): PrivateKey;
185
186
/**
187
* Convert private key to PEM format
188
* @param privateKey - Private key object
189
* @param maxline - Maximum line length for PEM output
190
* @returns PEM-encoded private key string
191
*/
192
forge.pki.privateKeyToPem(privateKey: PrivateKey, maxline?: number): string;
193
194
/**
195
* Convert public key from PEM format
196
* @param pem - PEM-encoded public key string
197
* @returns Public key object
198
*/
199
forge.pki.publicKeyFromPem(pem: string): PublicKey;
200
201
/**
202
* Convert public key to PEM format
203
* @param publicKey - Public key object
204
* @param maxline - Maximum line length for PEM output
205
* @returns PEM-encoded public key string
206
*/
207
forge.pki.publicKeyToPem(publicKey: PublicKey, maxline?: number): string;
208
```
209
210
**Usage Examples:**
211
212
```javascript
213
// Certificate PEM conversion
214
const certPem = forge.pki.certificateToPem(cert);
215
console.log('Certificate PEM:\n' + certPem);
216
217
// Load certificate from PEM
218
const loadedCert = forge.pki.certificateFromPem(certPem);
219
220
// Private key PEM conversion
221
const privateKeyPem = forge.pki.privateKeyToPem(keypair.privateKey);
222
const loadedPrivateKey = forge.pki.privateKeyFromPem(privateKeyPem);
223
224
// Public key PEM conversion
225
const publicKeyPem = forge.pki.publicKeyToPem(keypair.publicKey);
226
const loadedPublicKey = forge.pki.publicKeyFromPem(publicKeyPem);
227
```
228
229
### ASN.1 Format Conversion
230
231
Convert between ASN.1 DER format and JavaScript objects for low-level certificate operations.
232
233
```javascript { .api }
234
/**
235
* Convert certificate to ASN.1 format
236
* @param certificate - Certificate object
237
* @returns ASN.1 representation
238
*/
239
forge.pki.certificateToAsn1(certificate: Certificate): ASN1;
240
241
/**
242
* Convert certificate from ASN.1 format
243
* @param asn1 - ASN.1 certificate representation
244
* @returns Certificate object
245
*/
246
forge.pki.certificateFromAsn1(asn1: ASN1): Certificate;
247
248
/**
249
* Convert private key to ASN.1 format
250
* @param privateKey - Private key object
251
* @returns ASN.1 representation
252
*/
253
forge.pki.privateKeyToAsn1(privateKey: PrivateKey): ASN1;
254
255
/**
256
* Convert private key from ASN.1 format
257
* @param asn1 - ASN.1 private key representation
258
* @returns Private key object
259
*/
260
forge.pki.privateKeyFromAsn1(asn1: ASN1): PrivateKey;
261
262
/**
263
* Convert public key to ASN.1 format
264
* @param publicKey - Public key object
265
* @returns ASN.1 representation
266
*/
267
forge.pki.publicKeyToAsn1(publicKey: PublicKey): ASN1;
268
269
/**
270
* Convert public key from ASN.1 format
271
* @param asn1 - ASN.1 public key representation
272
* @returns Public key object
273
*/
274
forge.pki.publicKeyFromAsn1(asn1: ASN1): PublicKey;
275
```
276
277
### Certificate Extensions
278
279
Standard X.509 certificate extensions for enhanced functionality.
280
281
```javascript { .api }
282
interface CertificateExtension {
283
/** Extension name or OID */
284
name: string;
285
/** Extension identifier */
286
id?: string;
287
/** Critical flag */
288
critical?: boolean;
289
/** Extension value */
290
value?: any;
291
/** Alternative names (for Subject Alternative Name) */
292
altNames?: AltName[];
293
/** Key usage flags */
294
keyCertSign?: boolean;
295
digitalSignature?: boolean;
296
nonRepudiation?: boolean;
297
keyEncipherment?: boolean;
298
dataEncipherment?: boolean;
299
keyAgreement?: boolean;
300
keyCertSign?: boolean;
301
cRLSign?: boolean;
302
encipherOnly?: boolean;
303
decipherOnly?: boolean;
304
}
305
306
interface AltName {
307
/** Name type (1=email, 2=DNS, 6=URI, 7=IP) */
308
type: number;
309
/** Name value */
310
value: string;
311
/** IP address as bytes (for type 7) */
312
ip?: string;
313
}
314
```
315
316
**Usage Examples:**
317
318
```javascript
319
// Add certificate extensions
320
cert.setExtensions([
321
{
322
name: 'basicConstraints',
323
cA: true
324
},
325
{
326
name: 'keyUsage',
327
keyCertSign: true,
328
digitalSignature: true,
329
nonRepudiation: true,
330
keyEncipherment: true,
331
dataEncipherment: true
332
},
333
{
334
name: 'extKeyUsage',
335
serverAuth: true,
336
clientAuth: true,
337
codeSigning: true,
338
emailProtection: true,
339
timeStamping: true
340
},
341
{
342
name: 'subjectAltName',
343
altNames: [{
344
type: 2, // DNS
345
value: 'example.com'
346
}, {
347
type: 2, // DNS
348
value: 'www.example.com'
349
}, {
350
type: 7, // IP
351
ip: '127.0.0.1'
352
}]
353
}
354
]);
355
```
356
357
### Certificate Verification
358
359
Verify certificate chains and validate certificate properties.
360
361
```javascript { .api }
362
/**
363
* Create a certificate store for verification
364
* @param certs - Array of trusted CA certificates
365
* @returns Certificate store object
366
*/
367
forge.pki.createCertificateStore(certs?: Certificate[]): CertificateStore;
368
369
interface CertificateStore {
370
/**
371
* Add certificate to store
372
* @param cert - Certificate to add
373
*/
374
addCertificate(cert: Certificate | string): void;
375
376
/**
377
* Get certificate by subject hash
378
* @param hash - Subject hash
379
* @returns Certificate or null
380
*/
381
getCertificate(hash: string): Certificate | null;
382
383
/** Array of certificates in store */
384
certs: Certificate[];
385
}
386
387
/**
388
* Verify certificate chain
389
* @param caStore - Certificate store with trusted CAs
390
* @param chain - Certificate chain to verify
391
* @param options - Verification options
392
* @returns True if chain is valid
393
*/
394
forge.pki.verifyCertificateChain(
395
caStore: CertificateStore,
396
chain: Certificate[],
397
options?: VerificationOptions
398
): boolean;
399
400
interface VerificationOptions {
401
/** Verify certificate validity dates */
402
verify?: (verified: boolean, depth: number, chain: Certificate[]) => boolean;
403
/** Validation date (default: now) */
404
validityCheckDate?: Date;
405
}
406
```
407
408
**Usage Examples:**
409
410
```javascript
411
// Create certificate store with trusted CAs
412
const caStore = forge.pki.createCertificateStore();
413
caStore.addCertificate(caCert);
414
415
// Verify certificate
416
const verified = cert.verify(caStore);
417
console.log('Certificate verified:', verified);
418
419
// Verify certificate chain
420
const chain = [cert, intermediateCert];
421
const chainVerified = forge.pki.verifyCertificateChain(caStore, chain);
422
console.log('Chain verified:', chainVerified);
423
424
// Custom verification with date checking
425
const customVerified = forge.pki.verifyCertificateChain(caStore, chain, {
426
verify: (verified, depth, chain) => {
427
console.log(`Depth ${depth}: ${verified ? 'OK' : 'FAIL'}`);
428
return verified;
429
},
430
validityCheckDate: new Date('2023-01-01')
431
});
432
```
433
434
### Certificate Signing Request (CSR)
435
436
Create and process certificate signing requests.
437
438
```javascript { .api }
439
/**
440
* Create certificate signing request
441
* @returns CSR object
442
*/
443
forge.pki.createCertificationRequest(): CertificationRequest;
444
445
interface CertificationRequest {
446
/** CSR version */
447
version: number;
448
/** Subject information */
449
subject: CertificateSubject;
450
/** Public key */
451
publicKey: PublicKey;
452
/** Signature */
453
signature: string | null;
454
/** Signature algorithm */
455
signatureOid: string | null;
456
/** CSR attributes */
457
attributes: any[];
458
459
/**
460
* Sign the CSR with private key
461
* @param privateKey - Private key for signing
462
* @param md - Message digest (default: SHA-256)
463
*/
464
sign(privateKey: PrivateKey, md?: MessageDigest): void;
465
466
/**
467
* Verify CSR signature
468
* @returns True if signature is valid
469
*/
470
verify(): boolean;
471
}
472
473
/**
474
* Convert CSR to PEM format
475
* @param csr - CSR object
476
* @param maxline - Maximum line length
477
* @returns PEM-encoded CSR
478
*/
479
forge.pki.certificationRequestToPem(csr: CertificationRequest, maxline?: number): string;
480
481
/**
482
* Convert CSR from PEM format
483
* @param pem - PEM-encoded CSR
484
* @returns CSR object
485
*/
486
forge.pki.certificationRequestFromPem(pem: string): CertificationRequest;
487
```
488
489
**Usage Examples:**
490
491
```javascript
492
// Create certificate signing request
493
const csr = forge.pki.createCertificationRequest();
494
csr.publicKey = keypair.publicKey;
495
496
// Set CSR subject
497
csr.subject.attributes.push({
498
name: 'commonName',
499
value: 'example.com'
500
}, {
501
name: 'organizationName',
502
value: 'Example Corp'
503
});
504
505
// Sign CSR
506
csr.sign(keypair.privateKey, forge.md.sha256.create());
507
508
// Convert to PEM
509
const csrPem = forge.pki.certificationRequestToPem(csr);
510
console.log('CSR PEM:\n' + csrPem);
511
512
// Verify CSR
513
const isValid = csr.verify();
514
console.log('CSR valid:', isValid);
515
```
516
517
### Error Handling
518
519
Handle common PKI operation errors.
520
521
```javascript
522
try {
523
// Certificate operations
524
const cert = forge.pki.createCertificate();
525
cert.sign(privateKey);
526
527
// PEM conversion
528
const pem = forge.pki.certificateToPem(cert);
529
const loadedCert = forge.pki.certificateFromPem(pem);
530
531
// Verification
532
const verified = cert.verify(caStore);
533
534
} catch (error) {
535
// Handle errors:
536
// - Invalid PEM format
537
// - Missing required certificate fields
538
// - Invalid signatures
539
// - Expired certificates
540
// - Untrusted certificate chains
541
// - Malformed ASN.1 structures
542
console.error('PKI operation failed:', error.message);
543
}
544
```