57

RSA公開鍵暗号化を使用したい。秘密鍵と公開鍵を保存または取得するための最良の方法は何ですか?ここでXMLは良い考えですか?

キーを取得する方法は?

RSAParameters privateKey = RSA.ExportParameters(true);
RSAParameters publicKey = RSA.ExportParameters(false);

RSAParametersには次のメンバーがあるため:D、DP、DQ、指数、InverseQ、モジュラス、P、Q

どちらが鍵ですか?

4

6 に答える 6

216

私は、次のことを尋ねるalaによるコメントへの応答として何かを指摘したかった:

公開鍵=モジュラス+指数

それは正確に正しいです。これを保存する方法はいくつかありますexponent+ modulus。標準での最初の試みは、RFC 3447公開鍵暗号化標準(PKCS)#1:RSA暗号化仕様バージョン2.1)にありました。これは、次の公開鍵の構造を定義していますRSAPublicKey

RSAPublicKey ::= SEQUENCE {
      modulus           INTEGER,  -- n
      publicExponent    INTEGER   -- e
  }

同じRFCは、公開鍵を格納するためにDERフレーバーのASN.1エンコーディングを使用する必要があることを宣言しています。私はサンプルの公開鍵を持っています:

  • publicExponent:65537 (すべてのRSA公開鍵が指数として65537を使用するのが慣例です)
  • モジュラス0xDC 67 FA F4 9E F2 72 1D 45 2C B4 80 79 06 A0 94 27 50 8209 DD 67 CE 57 B8 6C 4A 4F 40 9F D2 D1 69 FB 995D 85 0C 07 A1 F9 47 1B 56 16 6E F6 7F B9 CF 2A 58 36 37 99 29 AA 4F A8 12 E8 4F C7 82 2B 9D 72 2A 9C DE 6F C2 EE 12 6D CF F0 F2 B8 C4 DD 7C 5C 1A C8 17 51 A9 AC DF 08 22 04 9D 2B D7 F9 4B 09 DE 9A EB 5C 51 1A D8 F8 F9 56 9E F8 FB 37 9B 3F D3 74 65 24 0D FF 34 75 57 A4 F5 BF 55

この公開鍵のDERASN.1エンコーディングは次のとおりです。

30 81 89          ;SEQUENCE (0x89 bytes = 137 bytes)
|  02 81 81       ;INTEGER (0x81 bytes = 129 bytes)
|  |  00          ;leading zero of INTEGER
|  |  DC 67 FA
|  |  F4 9E F2 72 1D 45 2C B4  80 79 06 A0 94 27 50 82
|  |  09 DD 67 CE 57 B8 6C 4A  4F 40 9F D2 D1 69 FB 99
|  |  5D 85 0C 07 A1 F9 47 1B  56 16 6E F6 7F B9 CF 2A
|  |  58 36 37 99 29 AA 4F A8  12 E8 4F C7 82 2B 9D 72
|  |  2A 9C DE 6F C2 EE 12 6D  CF F0 F2 B8 C4 DD 7C 5C
|  |  1A C8 17 51 A9 AC DF 08  22 04 9D 2B D7 F9 4B 09
|  |  DE 9A EB 5C 51 1A D8 F8  F9 56 9E F8 FB 37 9B 3F
|  |  D3 74 65 24 0D FF 34 75  57 A4 F5 BF 55
|  02 03          ;INTEGER (0x03 = 3 bytes)
|  |  01 00 01    ;hex for 65537. see it?

上記の全体をDERASN.1でエンコードした場合modulus+ exponent

30 81 89 02 81 81 00 DC 67 FA F4 9E F2 72 1D 45 2C B4 80 79 06 A0 94 27 50 82 09 DD 67 CE 57 B8 6C 4A 4F 40 9F D2 D1 69 FB 99 5D 85 0C 07 A1 F9 47 1B 56 16 6E F6 7F B9 CF 2A 58 36 37 99 29 AA 4F A8 12 E8 4F C7 82 2B 9D 72 2A 9C DE 6F C2 EE 12 6D CF F0 F2 B8 C4 DD 7C 5C 1A C8 17 51 A9 AC DF 08 22 04 9D 2B D7 F9 4B 09 DE 9A EB 5C 51 1A D8 F8 F9 56 9E F8 FB 37 9B 3F D3 74 65 24 0D FF 34 75 57 A4 F5 BF 55 02 03 01 00 01

そしてあなたはそれをPEMエンコードします(すなわちbase64):

MIGJAoGBANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXY
UMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE
3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dV
ek9b9VAgMBAAE=

そのbase64でエンコードされたデータを次のようにラップするのが慣例です。

-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXY
UMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE
3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dV
ek9b9VAgMBAAE=
-----END RSA PUBLIC KEY-----

これが、 PEM DER ASN.1 PKCS#1RSA公開鍵を取得する方法です。


次の標準はRFC4716Secure Shell(SSH)公開鍵ファイル形式)でした。ssh-rsaそれらには、指数とモジュラスの前にアルゴリズム識別子()が含まれていました。

string    "ssh-rsa"
mpint     e
mpint     n

彼らはDERASN.1エンコーディングを使用したくありませんでした(それはひどく複雑なので)、代わりに4バイトの長さのプレフィックスを選択しました:

00000007                 ;7 byte algorithm identifier
73 73 68 2d 72 73 61     ;"ssh-rsa"
00000003                 ;3 byte exponent
01 00 01                 ;hex for 65,537 
00000080                 ;128 byte modulus
DC 67 FA F4 9E F2 72 1D  45 2C B4 80 79 06 A0 94 
27 50 82 09 DD 67 CE 57  B8 6C 4A 4F 40 9F D2 D1 
69 FB 99 5D 85 0C 07 A1  F9 47 1B 56 16 6E F6 7F 
B9 CF 2A 58 36 37 99 29  AA 4F A8 12 E8 4F C7 82 
2B 9D 72 2A 9C DE 6F C2  EE 12 6D CF F0 F2 B8 C4 
DD 7C 5C 1A C8 17 51 A9  AC DF 08 22 04 9D 2B D7 
F9 4B 09 DE 9A EB 5C 51  1A D8 F8 F9 56 9E F8 FB 
37 9B 3F D3 74 65 24 0D  FF 34 75 57 A4 F5 BF 55

上記のバイトシーケンス全体を取得し、base-64でエンコードします。

AAAAB3NzaC1yc2EAAAADAQABAAAAgNxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hs
Sk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4S
bc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80
dVek9b9V

そして、それをOpenSSHヘッダーとトレーラーでラップします。

---- BEGIN SSH2 PUBLIC KEY ----
AAAAB3NzaC1yc2EAAAADAQABAAAAgNxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hs
Sk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4S
bc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80
dVek9b9V
---- END SSH2 PUBLIC KEY ----

:OpenSSHは---- 、5つのダッシュとスペースなし()ではなく、スペース付きの4つのダッシュ()を使用し-----ます。


次の標準はRFC2459インターネットX.509公開鍵インフラストラクチャ証明書とCRLプロファイル)でした。彼らはPKCS#1公開鍵形式を採用しました:

RSAPublicKey ::= SEQUENCE {
      modulus           INTEGER,  -- n
      publicExponent    INTEGER   -- e
  }

アルゴリズム識別子プレフィックスを含めるように拡張しました( RSA以外の公開鍵暗号化アルゴリズムを使用する場合)。

SubjectPublicKeyInfo  ::=  SEQUENCE  {
    algorithm            AlgorithmIdentifier,
    subjectPublicKey     RSAPublicKey }

RSAの「アルゴリズム識別子」1.2.840.113549.1.1.1は次のとおりです。

  • 1-ISOによって割り当てられたOID
    • 1.2-ISOメンバー本体
      • 1.2.840-米国
        • 1.2.840.113549-RSADSI
          • 1.2.840.113549.1-PKCS
            • 1.2.840.113549.1.1-PKCS-1

X.509はひどい標準であり、16進数にエンコードする非常に複雑な方法を定義していますが、最終的にX.509RSA公開鍵OIDのDERASN.1エンコードは次のようになります。SubjectPublicKeyInfo

30 81 9F            ;SEQUENCE (0x9f bytes = 159 bytes)
|  30 0D            ;SEQUENCE (0x0d bytes = 13 bytes)
|  |  06 09         ;OBJECT_IDENTIFIER (0x09 = 9 bytes)
|  |  2A 86 48 86   ;Hex encoding of 1.2.840.113549.1.1
|  |  F7 0D 01 01 01
|  |  05 00         ;NULL (0 bytes)
|  03 81 8D 00      ;BIT STRING (0x8d bytes = 141 bytes)
|  |  30 81 89          ;SEQUENCE (0x89 bytes = 137 bytes)
|  |  |  02 81 81       ;INTEGER (0x81 bytes = 129 bytes)
|  |  |  00          ;leading zero of INTEGER
|  |  |  DC 67 FA
|  |  |  F4 9E F2 72 1D 45 2C B4  80 79 06 A0 94 27 50 82
|  |  |  09 DD 67 CE 57 B8 6C 4A  4F 40 9F D2 D1 69 FB 99
|  |  |  5D 85 0C 07 A1 F9 47 1B  56 16 6E F6 7F B9 CF 2A
|  |  |  58 36 37 99 29 AA 4F A8  12 E8 4F C7 82 2B 9D 72
|  |  |  2A 9C DE 6F C2 EE 12 6D  CF F0 F2 B8 C4 DD 7C 5C
|  |  |  1A C8 17 51 A9 AC DF 08  22 04 9D 2B D7 F9 4B 09
|  |  |  DE 9A EB 5C 51 1A D8 F8  F9 56 9E F8 FB 37 9B 3F
|  |  |  D3 74 65 24 0D FF 34 75  57 A4 F5 BF 55
|  |  02 03          ;INTEGER (0x03 = 3 bytes)
|  |  |  01 00 01    ;hex for 65537. see it?

デコードされたASN.1で、古いものの前に.が付いていることがわかりRSAPublicKeyますOBJECT_IDENTIFIER

上記のバイトとそれらをエンコードするPEM(つまりbase-64)を取得します。

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcZ/r0nvJyHUUstIB5BqCUJ1CC
Cd1nzle4bEpPQJ/S0Wn7mV2FDAeh+UcbVhZu9n+5zypYNjeZKapPqBLoT8eCK51y
Kpzeb8LuEm3P8PK4xN18XBrIF1GprN8IIgSdK9f5SwnemutcURrY+PlWnvj7N5s/
03RlJA3/NHVXpPW/VQIDAQAB

標準では、これをRSA PKCS#1と同様のヘッダーでラップしますが、「RSA」は使用しません(RSA以外のものである可能性があるため)。

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcZ/r0nvJyHUUstIB5BqCUJ1CC
Cd1nzle4bEpPQJ/S0Wn7mV2FDAeh+UcbVhZu9n+5zypYNjeZKapPqBLoT8eCK51y
Kpzeb8LuEm3P8PK4xN18XBrIF1GprN8IIgSdK9f5SwnemutcURrY+PlWnvj7N5s/
03RlJA3/NHVXpPW/VQIDAQAB
-----END PUBLIC KEY-----

そして、それがX.509 SubjectPublicKeyInfo /OpenSSLPEM公開鍵形式を発明する方法です。


これは、RSA公開鍵の標準形式のリストを停止するものではありません。次は、OpenSSHで使用される独自の公開鍵形式です。

SSH-RSA AAAAB3NzaC1yc2EAAAADAQABAAAAgNxn + vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hs Sk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk + oEuhPx4IrnXIqnN5vwu4Sbc / w8rjE3XxcGsgXUams3wgiBJ0r1 / lLCd6a61xRGtj4 + VAE + Ps3mz / TdGUkDf80dVek9b9V

これは実際には上記のSSH公開鍵形式ですが、 /ssh-rsaでラップされるのではなく、プレフィックスが付けられます。---- BEGIN SSH2 PUBLIC KEY -------- END SSH2 PUBLIC KEY ----


ここで、 XMLRSAKeyValue公開鍵の使いやすさが重要になります。

  • 指数0x 010001base64でエンコードされたAQAB
  • モジュール0x 00 dc 67 fa f4 9e f2 72 1d 45 2c b4 80 79 06 a0 94 27 50 82 09 dd 67 ce 57 b8 6c 4a 4f 40 9f d2 d1 69 fb 99 5d 85 0c 07 a1 f9 47 1b 56 16 6e f6 7f b9 cf 2a 58 36 37 99 29 aa 4f a8 12 e8 4f c7 82 2b 9d 72 2a 9c de 6f c2 ee 12 6d cf f0 f2 b8 c4 dd 7c 5c 1a c8 17 51 a9 ac df 08 22 04 9d 2b d7 f9 4b 09 de 9a eb 5c 51 1a d8 f8 f9 56 9e f8 fb 37 9b 3f d3 74 65 24 0d ff 34 75 57 a4 f5 bf 55base64でエンコードされたものはANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9Vです。

これは、XMLが次のことを意味します。

<RSAKeyValue>
   <Modulus>ANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9V</Modulus>
   <Exponent>AQAB</Exponent>
</RSAKeyValue>

はるかに簡単です。欠点は、ラップ、コピー、貼り付けが、次のようにうまく行われないことです(つまり、Xmlはユーザーフレンドリーではありません)。

-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXY
UMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE
3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dV
ek9b9VAgMBAAE=
-----END RSA PUBLIC KEY-----

しかし、それは素晴らしいニュートラルなストレージフォーマットになります。

も参照してください

  • トランスレータ、バイナリ:base64データのデコードとエンコードに最適
  • ASN.1 JavaScriptデコーダー:ASN.1でエンコードされた16進データをデコードするのに最適です(Translator, Binary
  • Microsoft ASN.1ドキュメント:ASN.1構造に使用されるDistinguished Encoding Rules(DER)について説明します(他のどこにも優れたドキュメントのセットはありません。Microsoftのドキュメントは実際のドキュメントだけではないと思います)
于 2012-10-27T21:45:27.157 に答える
45

私が成功したのは、キーをXMLとして保存することです。RSACryptoServiceProviderには、ToXmlStringとFromXmlStringの2つのメソッドがあります。ToXmlStringは、パラメーターの設定方法に応じて、公開鍵データのみ、または公開鍵データと秘密鍵データの両方を含むXML文字列を返します。FromXmlStringメソッドは、公開鍵データのみ、または公開鍵データと秘密鍵データの両方を含むXML文字列が提供されると、RSACryptoServiceProviderに適切な鍵データを入力します。

于 2009-07-28T13:08:28.017 に答える
2

PEMなどの既存の標準形式を使用します。暗号ライブラリは、PEM形式のファイルからキーをロードおよび保存する機能を提供する必要があります。

指数とモジュラスは公開鍵です。DとModulusは秘密鍵です。他の値を使用すると、秘密鍵の所有者の計算を高速化できます。

于 2009-07-28T11:43:18.217 に答える
0

公開鍵は、モジュラスと指数によって識別されます。秘密鍵は他のメンバーによって識別されます。

于 2009-07-28T11:42:46.267 に答える
0

@Ian Boydからの回答は正確ではないと思います。SSH2用に定義されたRFC4716、OpenSSH形式は独自のものであるため、形式はOpenSSHではなくSSH2である必要があります。

注:OpenSSHは、5つのダッシュとスペースなし(-----)ではなく、スペース付きの4つのダッシュ(----)を使用します。

于 2021-12-27T09:20:58.353 に答える
-1

ここでXMLは良い考えですか?

通常、秘密鍵はHSM/スマートカードに保存されます。これにより、優れたセキュリティが提供されます。

于 2009-07-30T13:02:57.043 に答える