I want to use RSA public key encryption. What is the best way to store or retrieve private and public keys? Is XML a good idea here?
How to get the keys?
RSAParameters privateKey = RSA.ExportParameters(true);
RSAParameters publicKey = RSA.ExportParameters(false);
Because RSAParameters have the following members: D, DP, DQ, Exponent, InverseQ, Modulus, P, Q
Which one is the key?
Best Answer
i wanted to point out something as a response to a comment by ala asking if:
That is exactly correct. There are a few ways of storing this
exponent
+modulus
. The first attempt at a standard was in RFC 3447 (Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1), which defines a structure for a public key of calledRSAPublicKey
:The same RFC goes on to declare that you should use the DER flavor of
ASN.1
encoding to store the public key. i have a sample public key: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
The DER ASN.1 encoding of this public key is:
If you take that entire above DER ASN.1 encoded
modulus
+exponent
:and you PEM encode it (i.e. base64):
It's a convention to wrap that base64 encoded data in:
And that's how you get an have a PEM DER ASN.1 PKCS#1 RSA Public key.
The next standard was RFC 4716 (The Secure Shell (SSH) Public Key File Format). They included an algorithm identifier (
ssh-rsa
), before the exponent and modulus:They didn't want to use DER ASN.1 encoding (as it is horrendously complex), and instead opted for 4-byte length prefixing:
Take the entire above byte sequence and base-64 encode it:
And wrap it in the OpenSSH header and trailer:
Note: That OpenSSH uses four dashes with a space (
----
) rather than five dashes and no space (-----
).The next standard was RFC 2459 (Internet X.509 Public Key Infrastructure Certificate and CRL Profile). They took the PKCS#1 public key format:
and extended it to include an algorithm identifier prefix (in case you want to use a public key encryption algorithm other than RSA):
The "Algorithm Identifier" for RSA is
1.2.840.113549.1.1.1
, which comes from:1
- ISO assigned OIDs1.2
- ISO member body1.2.840
- USA1.2.840.113549
- RSADSI1.2.840.113549.1
- PKCS1.2.840.113549.1.1
- PKCS-1The X.509 is an awful standard, that defines a horribly complicated way of encoding an
OID
into hex, but in the end the DER ASN.1 encoding of an X.509SubjectPublicKeyInfo
RSA Public key is:You can see in the decoded ASN.1 how they just prefixed the old
RSAPublicKey
with anOBJECT_IDENTIFIER
.Taking the above bytes and PEM (i.e. base-64) encoding them:
The standard is then to wrap this with a header similar to RSA PKCS#1, but without the "RSA" (since it could be something other than RSA):
And that's how you invent an X.509 SubjectPublicKeyInfo/OpenSSL PEM public key format.
That doesn't stop the list of standard formats for an RSA public key. Next is the proprietary public key format used by OpenSSH:
Which is actually the SSH public key format above, but prefixed with
ssh-rsa
, rather than wrapped in---- BEGIN SSH2 PUBLIC KEY ----
/---- END SSH2 PUBLIC KEY ----
.This is where the ease of the XML
RSAKeyValue
public key comes in:0x 010001
base64 encoded isAQAB
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 55
base64 encoded isANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9V
.This means the XML is:
Much simpler. A downside is that it doesn't wrap, copy, paste, as nicely as (i.e. Xml is not as user friendly as):
But it makes a great neutral storage format.
See also
Translator, Binary