I know this is a similar question to this one but before I head down the Bouncey Castle route, does anyone know if its possible to load an RSA KeyPair from a .pem file (-----BEGIN RSA PRIVATE KEY-----) directly with the .NET 3.5 crypto library without having to go to a 3rd party or roll my own?
+5
A:
http://www.jensign.com/opensslkey/index.html
with source at http://www.jensign.com/opensslkey/opensslkey.cs
edit: excerpted relevant code:
first, extract the text between the ---- BEGIN ---- and ---- END ---- sections, and base64-decode it into a byte array (see link above for details), then pass it to:
//------- Parses binary ans.1 RSA private key; returns RSACryptoServiceProvider ---
public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
MemoryStream mem = new MemoryStream(privkey) ;
BinaryReader binr = new BinaryReader(mem) ; //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try {
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
bt = binr.ReadByte();
if (bt !=0x00)
return null;
//------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems) ;
elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems) ;
elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems) ;
elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems) ;
elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems) ;
elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems) ;
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems) ;
Console.WriteLine("showing components ..");
if (verbose) {
showBytes("\nModulus", MODULUS) ;
showBytes("\nExponent", E);
showBytes("\nD", D);
showBytes("\nP", P);
showBytes("\nQ", Q);
showBytes("\nDP", DP);
showBytes("\nDQ", DQ);
showBytes("\nIQ", IQ);
}
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus =MODULUS;
RSAparams.Exponent = E;
RSAparams.D = D;
RSAparams.P = P;
RSAparams.Q = Q;
RSAparams.DP = DP;
RSAparams.DQ = DQ;
RSAparams.InverseQ = IQ;
RSA.ImportParameters(RSAparams);
return RSA;
}
catch (Exception) {
return null;
}
finally {
binr.Close();
}
}
Stobor
2009-07-22 00:52:24
Never mind; that was the solution from the other question.
Stobor
2009-07-22 00:58:11
I'll give this a go...what did you mean that was the solution for the other question? The accepted answer to question I referenced used the Bouncy Castle library (which works for me as well by the way). I am just wanting to minimise my reliance on 3rd party libraries where possible. Even those with very generous licensing.
Tim Jarvis
2009-07-22 01:16:25
@Tim Jarvis: the top answer for the other question currently is "You might take a look at JavaScience's source for OpenSSLKey." That's the same as what I've linked and copied above. (BouncyCastle is how the questioner answered it themselves, not the accepted answer...)
Stobor
2009-07-22 02:17:53
ah, of course. Cheers. Haven't tried this yet...about to go have some lunch. Will let you know how it goes. (thx by the way +1 with maybe a +15 to come)
Tim Jarvis
2009-07-22 02:28:07
Well, I don't know why this didn't work for the poster of the other question, but it worked fine for me. (with a couple minor mods.)
Tim Jarvis
2009-07-22 05:21:49