2

RSA秘密鍵を指定すると...

-----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-----

装甲がなく、base64 でデコードすると...

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 

そこからすべての数値を配列に抽出しました...

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

わからないのは...

1. 抽出された値の一部に先行があるものとないものがあるのはなぜ00ですか?

2. 最初の値 ( 00) の目的は何ですか? 私には冗長に思えます。

私が知りたい理由は、javascript で RSA キーを生成したいからです。必要な数値を生成していますが、先頭に s が必要なタイミングがわかりません00

編集

あと、全体の最初の部分がよくわかりません…

30 82 01 3a

がメッセージの残りの長さであることは理解していますが、 が何を表し01 3aているのかわかりません。30 82

3.30 82デコードされたキーの先頭にある は何ですか?

4

2 に答える 2

2

答えのほとんどはここにあります:http://pumka.net/2009/12/19/reading-writing-and-converting-rsa-keys-in-pem-der-publickeyblob-and-privatekeyblob-formats/

  1. DERの多くの整数値はゼロバイトで始まることに注意してください。これは、ASN.1標準では、マルチバイト整数の最初のビットが1に設定されている場合、マルチバイト整数の先頭にゼロバイトを追加する必要があるためです。

  2. @Gwynの回答の後に更新(http://www.regular-expressions.info/conditional.htmlこれはバージョン番号であり、現在はマルチプライムと通常を区別するためだけに使用されますが、RSAのリビジョンを区別するためにも使用されます。スペック

  3. 差出人: http: //msdn.microsoft.com/en-us/library/windows/desktop/bb648645 (v = vs.85).aspxおよび:http ://msdn.microsoft.com/en-us/library/ windows / desktop / bb648641(v = vs.85).aspx

SEQUENCEには、1つ以上のタイプの順序フィールドが含まれています。これは、0x30のタグバイトで始まるTLVトリプレットにエンコードされます。

..。

SEQUENCEに含まれるバイトが128バイト未満の場合、TLVトリプレットの長さフィールドでコンテンツの長さを指定するのに必要なバイトは1バイトだけです。127バイトを超える場合、長さフィールドのビット7は1に設定され、ビット6から0は、コンテンツの長さを識別するために使用される追加のバイト数を指定します。

コード...

これはjavascriptコードですが、少しラフですが、JavaScriptを使用してOpenSSLと相互運用できるように、RSAキーを生成する方法と、キー生成に必要な数値を入力する方法の実用的な証拠です...

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)
于 2013-02-13T12:42:45.940 に答える
1

2に答えるだけで、他の人が対処しているように、最初の00はバージョンフィールドです。ここでASN.1デコーダーを使用して、Base64または16進数をデコードし、9整数のシーケンスを表示します。仕様(A.1.2を参照)をチェックして、それらが何であるかを確認する必要がありますが、決定的なものではありませんが、ウィキペディアにはここにいくつかの情報があります

于 2013-02-21T23:15:20.017 に答える