0
# ASN.1 Encoding and Decoding
1
2
ASN.1 DER encoding/decoding for working with cryptographic standards and certificate formats. Node-forge provides comprehensive ASN.1 support for parsing and generating binary data structures used in PKI and cryptographic protocols.
3
4
## Capabilities
5
6
### ASN.1 Object Creation
7
8
Create ASN.1 objects with specified tag class, type, and value.
9
10
```javascript { .api }
11
/**
12
* Create an ASN.1 object
13
* @param tagClass - ASN.1 tag class (UNIVERSAL, APPLICATION, CONTEXT_SPECIFIC, PRIVATE)
14
* @param type - ASN.1 type identifier
15
* @param constructed - True if constructed from other ASN.1 objects
16
* @param value - Value content (string for primitive types, array for constructed)
17
* @param options - Additional options
18
* @returns ASN.1 object
19
*/
20
forge.asn1.create(
21
tagClass: number,
22
type: number,
23
constructed: boolean,
24
value: any,
25
options?: ASN1Options
26
): ASN1;
27
28
interface ASN1 {
29
/** ASN.1 tag class */
30
tagClass: number;
31
/** ASN.1 type identifier */
32
type: number;
33
/** Whether this is a constructed type */
34
constructed: boolean;
35
/** Value content */
36
value: any;
37
/** Original encoding (for validation) */
38
original?: ASN1;
39
}
40
41
interface ASN1Options {
42
/** Validate against original encoding */
43
validate?: boolean;
44
}
45
```
46
47
**Usage Examples:**
48
49
```javascript
50
const forge = require('node-forge');
51
52
// Create primitive ASN.1 objects
53
const boolean = forge.asn1.create(
54
forge.asn1.Class.UNIVERSAL,
55
forge.asn1.Type.BOOLEAN,
56
false,
57
'\x01' // TRUE
58
);
59
60
const integer = forge.asn1.create(
61
forge.asn1.Class.UNIVERSAL,
62
forge.asn1.Type.INTEGER,
63
false,
64
'\x01\x00' // 256 in two's complement
65
);
66
67
const octetString = forge.asn1.create(
68
forge.asn1.Class.UNIVERSAL,
69
forge.asn1.Type.OCTETSTRING,
70
false,
71
'Hello World'
72
);
73
74
// Create constructed ASN.1 objects
75
const sequence = forge.asn1.create(
76
forge.asn1.Class.UNIVERSAL,
77
forge.asn1.Type.SEQUENCE,
78
true,
79
[boolean, integer, octetString]
80
);
81
```
82
83
### ASN.1 Constants
84
85
Standard ASN.1 tag classes and types for constructing valid structures.
86
87
```javascript { .api }
88
/**
89
* ASN.1 tag classes
90
*/
91
forge.asn1.Class = {
92
UNIVERSAL: 0x00; // Standard universal types
93
APPLICATION: 0x40; // Application-specific types
94
CONTEXT_SPECIFIC: 0x80; // Context-specific types
95
PRIVATE: 0xC0; // Private types
96
};
97
98
/**
99
* ASN.1 universal types
100
*/
101
forge.asn1.Type = {
102
NONE: 0;
103
BOOLEAN: 1; // Boolean value
104
INTEGER: 2; // Integer value
105
BITSTRING: 3; // Bit string
106
OCTETSTRING: 4; // Octet (byte) string
107
NULL: 5; // Null value
108
OID: 6; // Object identifier
109
ODESC: 7; // Object descriptor
110
EXTERNAL: 8; // External type
111
REAL: 9; // Real number
112
ENUMERATED: 10; // Enumerated value
113
EMBEDDED_PDV: 11; // Embedded PDV
114
UTF8: 12; // UTF-8 string
115
SEQUENCE: 16; // Sequence (ordered collection)
116
SET: 17; // Set (unordered collection)
117
PRINTABLESTRING: 19; // Printable string
118
T61STRING: 20; // T61 string
119
VIDEOTEXSTRING: 21; // Videotex string
120
IA5STRING: 22; // IA5 string
121
UTCTIME: 23; // UTC time
122
GENERALIZEDTIME: 24; // Generalized time
123
GRAPHICSTRING: 25; // Graphic string
124
VISIBLESTRING: 26; // Visible string
125
GENERALSTRING: 27; // General string
126
UNIVERSALSTRING: 28; // Universal string
127
BMPSTRING: 30; // BMP string
128
};
129
```
130
131
### DER Encoding and Decoding
132
133
Convert between ASN.1 objects and DER (Distinguished Encoding Rules) binary format.
134
135
```javascript { .api }
136
/**
137
* Parse ASN.1 object from DER encoding
138
* @param bytes - DER-encoded bytes as string or ByteStringBuffer
139
* @param strict - Strict parsing mode (default: true)
140
* @returns Parsed ASN.1 object
141
*/
142
forge.asn1.fromDer(bytes: string | ByteStringBuffer, strict?: boolean): ASN1;
143
144
/**
145
* Encode ASN.1 object to DER format
146
* @param asn1Object - ASN.1 object to encode
147
* @returns DER-encoded bytes as ByteStringBuffer
148
*/
149
forge.asn1.toDer(asn1Object: ASN1): ByteStringBuffer;
150
```
151
152
**Usage Examples:**
153
154
```javascript
155
// Create ASN.1 structure and encode to DER
156
const sequence = forge.asn1.create(
157
forge.asn1.Class.UNIVERSAL,
158
forge.asn1.Type.SEQUENCE,
159
true,
160
[
161
forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.INTEGER, false, '\x01'),
162
forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.OCTETSTRING, false, 'test')
163
]
164
);
165
166
// Encode to DER
167
const derBytes = forge.asn1.toDer(sequence);
168
console.log('DER bytes:', derBytes.toHex());
169
170
// Parse from DER
171
const parsed = forge.asn1.fromDer(derBytes);
172
console.log('Parsed ASN.1:', parsed);
173
174
// Access parsed values
175
console.log('First element (integer):', parsed.value[0].value);
176
console.log('Second element (string):', parsed.value[1].value);
177
```
178
179
### ASN.1 Object Operations
180
181
Utility functions for working with ASN.1 objects.
182
183
```javascript { .api }
184
/**
185
* Copy an ASN.1 object
186
* @param asn1Object - ASN.1 object to copy
187
* @param options - Copy options
188
* @returns Deep copy of ASN.1 object
189
*/
190
forge.asn1.copy(asn1Object: ASN1, options?: any): ASN1;
191
192
/**
193
* Compare two ASN.1 objects for equality
194
* @param obj1 - First ASN.1 object
195
* @param obj2 - Second ASN.1 object
196
* @returns True if objects are equal
197
*/
198
forge.asn1.equals(obj1: ASN1, obj2: ASN1): boolean;
199
200
/**
201
* Get length of ASN.1 object when encoded
202
* @param asn1Object - ASN.1 object
203
* @returns Length in bytes
204
*/
205
forge.asn1.getBerValueLength(asn1Object: ASN1): number;
206
```
207
208
**Usage Examples:**
209
210
```javascript
211
// Copy ASN.1 object
212
const original = forge.asn1.create(
213
forge.asn1.Class.UNIVERSAL,
214
forge.asn1.Type.INTEGER,
215
false,
216
'\x01\x00'
217
);
218
const copy = forge.asn1.copy(original);
219
220
// Compare objects
221
const isEqual = forge.asn1.equals(original, copy);
222
console.log('Objects equal:', isEqual); // true
223
224
// Get encoded length
225
const length = forge.asn1.getBerValueLength(original);
226
console.log('Encoded length:', length);
227
```
228
229
### Object Identifier (OID) Support
230
231
Handle Object Identifiers for algorithm and attribute identification.
232
233
```javascript { .api }
234
/**
235
* Convert OID string to DER encoding
236
* @param oid - OID string (e.g., "1.2.840.113549.1.1.1")
237
* @returns DER-encoded OID as ByteStringBuffer
238
*/
239
forge.asn1.oidToDer(oid: string): ByteStringBuffer;
240
241
/**
242
* Convert DER-encoded OID to string
243
* @param bytes - DER-encoded OID bytes
244
* @returns OID string
245
*/
246
forge.asn1.derToOid(bytes: string | ByteStringBuffer): string;
247
248
/**
249
* Validate OID string format
250
* @param oid - OID string to validate
251
* @returns True if valid OID format
252
*/
253
forge.asn1.validateOid(oid: string): boolean;
254
```
255
256
**Usage Examples:**
257
258
```javascript
259
// Work with Object Identifiers
260
const rsaOid = '1.2.840.113549.1.1.1'; // RSA encryption OID
261
const derOid = forge.asn1.oidToDer(rsaOid);
262
console.log('DER-encoded OID:', derOid.toHex());
263
264
// Convert back to string
265
const oidString = forge.asn1.derToOid(derOid);
266
console.log('OID string:', oidString); // "1.2.840.113549.1.1.1"
267
268
// Create OID ASN.1 object
269
const oidAsn1 = forge.asn1.create(
270
forge.asn1.Class.UNIVERSAL,
271
forge.asn1.Type.OID,
272
false,
273
derOid.getBytes()
274
);
275
```
276
277
### Date and Time Handling
278
279
Convert between JavaScript Date objects and ASN.1 time representations.
280
281
```javascript { .api }
282
/**
283
* Convert UTC time to JavaScript Date
284
* @param utc - ASN.1 UTC time string (YYMMDDHHMMSSZ format)
285
* @returns JavaScript Date object
286
*/
287
forge.asn1.utcTimeToDate(utc: string): Date;
288
289
/**
290
* Convert generalized time to JavaScript Date
291
* @param gentime - ASN.1 generalized time string (YYYYMMDDHHMMSSZ format)
292
* @returns JavaScript Date object
293
*/
294
forge.asn1.generalizedTimeToDate(gentime: string): Date;
295
296
/**
297
* Convert JavaScript Date to UTC time string
298
* @param date - JavaScript Date object
299
* @returns ASN.1 UTC time string
300
*/
301
forge.asn1.dateToUtcTime(date: Date): string;
302
303
/**
304
* Convert JavaScript Date to generalized time string
305
* @param date - JavaScript Date object
306
* @returns ASN.1 generalized time string
307
*/
308
forge.asn1.dateToGeneralizedTime(date: Date): string;
309
```
310
311
**Usage Examples:**
312
313
```javascript
314
// Work with ASN.1 time types
315
const now = new Date();
316
317
// Create UTC time (valid until 2049)
318
const utcTime = forge.asn1.dateToUtcTime(now);
319
const utcAsn1 = forge.asn1.create(
320
forge.asn1.Class.UNIVERSAL,
321
forge.asn1.Type.UTCTIME,
322
false,
323
utcTime
324
);
325
326
// Create generalized time (valid beyond 2049)
327
const genTime = forge.asn1.dateToGeneralizedTime(now);
328
const genAsn1 = forge.asn1.create(
329
forge.asn1.Class.UNIVERSAL,
330
forge.asn1.Type.GENERALIZEDTIME,
331
false,
332
genTime
333
);
334
335
// Parse time values back to Date
336
const parsedUtc = forge.asn1.utcTimeToDate(utcTime);
337
const parsedGen = forge.asn1.generalizedTimeToDate(genTime);
338
console.log('Parsed UTC time:', parsedUtc);
339
console.log('Parsed generalized time:', parsedGen);
340
```
341
342
### Advanced ASN.1 Structures
343
344
Build complex ASN.1 structures commonly used in cryptographic applications.
345
346
**Usage Examples:**
347
348
```javascript
349
// Create X.509 certificate validity structure
350
function createValidity(notBefore, notAfter) {
351
return forge.asn1.create(
352
forge.asn1.Class.UNIVERSAL,
353
forge.asn1.Type.SEQUENCE,
354
true,
355
[
356
forge.asn1.create(
357
forge.asn1.Class.UNIVERSAL,
358
forge.asn1.Type.UTCTIME,
359
false,
360
forge.asn1.dateToUtcTime(notBefore)
361
),
362
forge.asn1.create(
363
forge.asn1.Class.UNIVERSAL,
364
forge.asn1.Type.UTCTIME,
365
false,
366
forge.asn1.dateToUtcTime(notAfter)
367
)
368
]
369
);
370
}
371
372
// Create algorithm identifier structure
373
function createAlgorithmIdentifier(oid, parameters = null) {
374
const sequence = [
375
forge.asn1.create(
376
forge.asn1.Class.UNIVERSAL,
377
forge.asn1.Type.OID,
378
false,
379
forge.asn1.oidToDer(oid).getBytes()
380
)
381
];
382
383
if (parameters !== null) {
384
sequence.push(parameters);
385
} else {
386
sequence.push(
387
forge.asn1.create(
388
forge.asn1.Class.UNIVERSAL,
389
forge.asn1.Type.NULL,
390
false,
391
''
392
)
393
);
394
}
395
396
return forge.asn1.create(
397
forge.asn1.Class.UNIVERSAL,
398
forge.asn1.Type.SEQUENCE,
399
true,
400
sequence
401
);
402
}
403
404
// Use the structures
405
const validity = createValidity(new Date(), new Date(Date.now() + 365*24*60*60*1000));
406
const rsaAlgId = createAlgorithmIdentifier('1.2.840.113549.1.1.1'); // RSA
407
```
408
409
### Error Handling
410
411
Handle common ASN.1 parsing and encoding errors.
412
413
```javascript
414
try {
415
// Parse potentially malformed DER data
416
const asn1Obj = forge.asn1.fromDer(derBytes, true); // strict mode
417
418
// Encode ASN.1 object
419
const encoded = forge.asn1.toDer(asn1Obj);
420
421
// Validate OID
422
const oid = '1.2.840.113549.1.1.1';
423
if (!forge.asn1.validateOid(oid)) {
424
throw new Error('Invalid OID format');
425
}
426
427
} catch (error) {
428
// Handle errors:
429
// - Malformed DER encoding
430
// - Invalid ASN.1 structure
431
// - Unsupported ASN.1 types
432
// - Invalid OID format
433
// - Date/time conversion errors
434
// - Length encoding errors
435
console.error('ASN.1 operation failed:', error.message);
436
}
437
```
438
439
### Performance Considerations
440
441
Optimize ASN.1 operations for better performance.
442
443
**Usage Examples:**
444
445
```javascript
446
// Efficient parsing of large ASN.1 structures
447
function parseSequenceElements(seq) {
448
const elements = [];
449
if (seq.constructed && seq.value) {
450
for (let i = 0; i < seq.value.length; i++) {
451
elements.push(seq.value[i]);
452
}
453
}
454
return elements;
455
}
456
457
// Reuse OID encodings for better performance
458
const commonOids = {
459
RSA: forge.asn1.oidToDer('1.2.840.113549.1.1.1'),
460
SHA256: forge.asn1.oidToDer('2.16.840.1.101.3.4.2.1'),
461
MD5: forge.asn1.oidToDer('1.2.840.113549.2.5')
462
};
463
464
// Use cached OID encodings
465
function createRsaAlgorithmId() {
466
return forge.asn1.create(
467
forge.asn1.Class.UNIVERSAL,
468
forge.asn1.Type.SEQUENCE,
469
true,
470
[
471
forge.asn1.create(
472
forge.asn1.Class.UNIVERSAL,
473
forge.asn1.Type.OID,
474
false,
475
commonOids.RSA.getBytes()
476
),
477
forge.asn1.create(
478
forge.asn1.Class.UNIVERSAL,
479
forge.asn1.Type.NULL,
480
false,
481
''
482
)
483
]
484
);
485
}
486
```