Given an RSA private key...

```
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAMpZrx0gTluJEu6+fop1e60lwbnlBD6kHvoRx85GBhUgD8SQknjc
LcU2qqM/pV9ZX8MV8x49h2mzrmRyH7kDmpcCAwEAAQJAYf2GYMt5Rrids4IKk5CL
IPFs3FH8eT1PRvh/UvP0FBwDMZu/Q4m+3PNTM3ARQhFuCvWgCalMmZkyVx0HYRLe
4QIhAOaaQm+b/bSoHqolvVTcyfBL09rrLFZhgGkETX3R6cVRAiEA4KLdUm97YBxP
T6/jkn/P7K8SUWEO9o9u8Bif1UKQB2cCIETqoSQ92EqfW9q5wKWV/nvkDYKFehCu
vvOjp40MqPKhAiA2sPBZpbLQD5Rvvk8V1/Bzm5xGG+9csEc+RYCEl5QheQIhAKgi
Xb3zY9lqtpX/mgTIrW6RPB3GocviJOibqtpfNxRU
-----END RSA PRIVATE KEY-----
```

Unarmoured, and base64 decoded gives...

```
30 82 01 3a 02 01 00 02 41 00 ca 59 af 1d 20 4e 5b 89 12 ee be 7e 8a 75 7b ad 25 c1 b9 e5 04 3e
a4 1e fa 11 c7 ce 46 06 15 20 0f c4 90 92 78 dc 2d c5 36 aa a3 3f a5 5f 59 5f c3 15 f3 1e 3d 87
69 b3 ae 64 72 1f b9 03 9a 97 02 03 01 00 01 02 40 61 fd 86 60 cb 79 46 b8 9d b3 82 0a 93 90 8b
20 f1 6c dc 51 fc 79 3d 4f 46 f8 7f 52 f3 f4 14 1c 03 31 9b bf 43 89 be dc f3 53 33 70 11 42 11
6e 0a f5 a0 09 a9 4c 99 99 32 57 1d 07 61 12 de e1 02 21 00 e6 9a 42 6f 9b fd b4 a8 1e aa 25 bd
54 dc c9 f0 4b d3 da eb 2c 56 61 80 69 04 4d 7d d1 e9 c5 51 02 21 00 e0 a2 dd 52 6f 7b 60 1c 4f
4f af e3 92 7f cf ec af 12 51 61 0e f6 8f 6e f0 18 9f d5 42 90 07 67 02 20 44 ea a1 24 3d d8 4a
9f 5b da b9 c0 a5 95 fe 7b e4 0d 82 85 7a 10 ae be f3 a3 a7 8d 0c a8 f2 a1 02 20 36 b0 f0 59 a5
b2 d0 0f 94 6f be 4f 15 d7 f0 73 9b 9c 46 1b ef 5c b0 47 3e 45 80 84 97 94 21 79 02 21 00 a8 22
5d bd f3 63 d9 6a b6 95 ff 9a 04 c8 ad 6e 91 3c 1d c6 a1 cb e2 24 e8 9b aa da 5f 37 14 54
```

I extracted all the numbers from it, into an array...

```
[ '00',
'00ca59af1d204e5b8912eebe7e8a757bad25c1b9e5043ea41efa11c7ce460615200fc4909278dc2dc536aaa33fa55f595fc315f31e3d8769b3ae64721fb9039a97',
'010001',
'61fd8660cb7946b89db3820a93908b20f16cdc51fc793d4f46f87f52f3f4141c03319bbf4389bedcf35333701142116e0af5a009a94c999932571d076112dee1',
'00e69a426f9bfdb4a81eaa25bd54dcc9f04bd3daeb2c56618069044d7dd1e9c551',
'00e0a2dd526f7b601c4f4fafe3927fcfecaf1251610ef68f6ef0189fd542900767',
'44eaa1243dd84a9f5bdab9c0a595fe7be40d82857a10aebef3a3a78d0ca8f2a1',
'36b0f059a5b2d00f946fbe4f15d7f0739b9c461bef5cb0473e45808497942179',
'00a8225dbdf363d96ab695ff9a04c8ad6e913c1dc6a1cbe224e89baada5f371454'
]
```

What I don't understand is...

### 1. Why some of the extracted values have leading `00`

and some don't?

### 2. What is the purpose of the first value (`00`

)? It seems redundant to me.

The reason I want to know, is I want to generate RSA keys in javascript. I am generating the numbers required, but I don't know when they should have leading `00`

s.

**EDIT**

Also, I don't quite understand the first part of the whole thing...

```
30 82 01 3a
```

I understand the `01 3a`

is the length of the rest of the message, but I don't know what the `30 82`

represents.

### 3. What is the `30 82`

at the start of the decoded key?

Most of the answers are here: http://pumka.net/2009/12/19/reading-writing-and-converting-rsa-keys-in-pem-der-publickeyblob-and-privatekeyblob-formats/

Notice that many integer values in DER begin with a zero byte. That's because ASN.1 standard requires adding zero byte to the beginning of multi-byte integer if the first bit of it is set to 1.

*Upadated after @Gwyn's answer (http://www.regular-expressions.info/conditional.html)*It is the version number, currently only to distinguish multi-prime from normal, but will also be used to distinguish between revisions of the RSA specFrom: http://msdn.microsoft.com/en-us/library/windows/desktop/bb648645(v=vs.85).aspx And: http://msdn.microsoft.com/en-us/library/windows/desktop/bb648641(v=vs.85).aspx

A SEQUENCE contains an ordered field of one or more types. It is encoded into a TLV triplet that begins with a Tag byte of 0x30.

...

If the SEQUENCE contains fewer than 128 bytes, the Length field of the TLV triplet requires only one byte to specify the content length. If it is more than 127 bytes, bit 7 of the Length field is set to 1 and bits 6 through 0 specify the number of additional bytes used to identify the content length.

## The Code...

Here is the javascript code, a bit rough, but a working proof of how to generate RSA keys, to be interoperable with OpenSSL using javascript, and an input of the required numbers for key generation...

```
function hex2b64(h) {
var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var b64pad="=";
var i;
var c;
var ret = "";
for(i = 0; i+3 <= h.length; i+=3) {
c = parseInt(h.substring(i,i+3),16);
ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
}
if(i+1 == h.length) {
c = parseInt(h.substring(i,i+1),16);
ret += b64map.charAt(c << 2);
}
else if(i+2 == h.length) {
c = parseInt(h.substring(i,i+2),16);
ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
}
while((ret.length & 3) > 0) ret += b64pad;
return ret;
}
var private_key = "-----BEGIN RSA PRIVATE KEY-----\n"+
"MIIBOgIBAAJBAMpZrx0gTluJEu6+fop1e60lwbnlBD6kHvoRx85GBhUgD8SQknjc\n"+
"LcU2qqM/pV9ZX8MV8x49h2mzrmRyH7kDmpcCAwEAAQJAYf2GYMt5Rrids4IKk5CL\n"+
"IPFs3FH8eT1PRvh/UvP0FBwDMZu/Q4m+3PNTM3ARQhFuCvWgCalMmZkyVx0HYRLe\n"+
"4QIhAOaaQm+b/bSoHqolvVTcyfBL09rrLFZhgGkETX3R6cVRAiEA4KLdUm97YBxP\n"+
"T6/jkn/P7K8SUWEO9o9u8Bif1UKQB2cCIETqoSQ92EqfW9q5wKWV/nvkDYKFehCu\n"+
"vvOjp40MqPKhAiA2sPBZpbLQD5Rvvk8V1/Bzm5xGG+9csEc+RYCEl5QheQIhAKgi\n"+
"Xb3zY9lqtpX/mgTIrW6RPB3GocviJOibqtpfNxRU\n"+
"-----END RSA PRIVATE KEY-----";
// these numbers have been extracted from the given RSA private key
numbers = ['00',
'ca59af1d204e5b8912eebe7e8a757bad25c1b9e5043ea41efa11c7ce460615200fc4909278dc2dc536aaa33fa55f595fc315f31e3d8769b3ae64721fb9039a97',
'010001',
'61fd8660cb7946b89db3820a93908b20f16cdc51fc793d4f46f87f52f3f4141c03319bbf4389bedcf35333701142116e0af5a009a94c999932571d076112dee1',
'e69a426f9bfdb4a81eaa25bd54dcc9f04bd3daeb2c56618069044d7dd1e9c551',
'e0a2dd526f7b601c4f4fafe3927fcfecaf1251610ef68f6ef0189fd542900767',
'44eaa1243dd84a9f5bdab9c0a595fe7be40d82857a10aebef3a3a78d0ca8f2a1',
'36b0f059a5b2d00f946fbe4f15d7f0739b9c461bef5cb0473e45808497942179',
'a8225dbdf363d96ab695ff9a04c8ad6e913c1dc6a1cbe224e89baada5f371454' ]
var data = ""
// loop through all the numbers
for(i in numbers){
var item = numbers[i]
// if the first binary bit is 1 (if the first hex pair is greater than 127)
// add a `00` prefix, as ASN1 demands
if(parseInt(item.match(/^../),16) > 127){ item = "00"+item }
// calculate the length
var len = ("0"+(item.length/2).toString(16)).replace(/.(..)/,"$1")
// build data string, the `02` is ASN1 code for string
data += "02"+len+item
// can check all the input data here
// console.log("02", len, item)
}
// calculate the length of all the data
var datalen = (data.length/2).toString(16)
// add leading `0` if required to ensure hex pairs
if(datalen.length % 2 == 1){ datalen = "0"+datalen }
// set the extra bits to define the length if required, or make it empty
var exlen = parseInt(datalen,16) >= 128 ? (datalen.length/2 + 128).toString(16) : ''
// create the full data string
var full_data = "30"+exlen+datalen+data
// encode the data
var encoded = hex2b64(full_data)
// split it into lines no longer than 64 characters
var lines = encoded.match(/.{1,64}/g)
// add the armour
lines.unshift("-----BEGIN RSA PRIVATE KEY-----")
lines.push("-----END RSA PRIVATE KEY-----")
// join it all together
var generated_key = lines.join("\n")
// check if the generated key matches the expected key
console.log(generated_key == private_key)
```