如何将由openSSL生成的RSA公钥加载到RSACryptoServiceProvider中?
我写一个.NET类读取从我们的中央认证服务器的cookie。它包含UserId,一些时间戳和由openssl_sign()使用2048位RSA密钥和SHA1哈希创建的签名。如何将由openSSL生成的RSA公钥加载到RSACryptoServiceProvider中?
当前的公钥OpenSSL中的PEM格式提供的服务器和偶尔的变化上。我无法读取使用的.Net独(还)托管代码,并制定了以下程序得到它的工作重点:从公钥
- 提取指数和模量仍然是2048位
- 存储密钥长度,指数在资源的弹性模量,编译和部署(从模量下降,导致零,使其工作)
的类,然后创建一个new RSACryptoServiceProvider(2048)
并使用RSAParameters
结构到CSP饲料公共组件。验证签名然后成功。
我希望得到这个工作没有我创建,编译和每次部署新议会的主要变化。为了使事情变得有趣,我只想坚持托管代码(排除我发现的大多数例子)。创造AsnEncodedData(oid, data)
实例,但我发现,可以匹配的唯一OID,RSA又名1.2.840.113549.1.1.1时,没有工作,只生产原始字节的东西,听起来很完美,是内部ASN.1读者。
补充:前公钥
----- BEGIN PUBLIC KEY -----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMW90O6C17fapbS35auKolsy7kI0FOE1
C08y5HqgZ0rMXoocV4nHSHYBm2HVx2QSR5OLQtERgWDmxOu + vwU1GXUCAwEAAQ ==
----- END PUBLIC KEY-- ---
我发现pempublic.cs似乎解决这个使用(因为它似乎)来自openSSL的源代码。我将留下这个问题,看看是否有其他解决方案。
你的私钥,所以它可能更容易产生从密钥自签名证书。您可以使用System.Security.Cryptography.X509Certificates.X509Certificate
(我想你应该有DER/ASN.1格式,而吴丹PEM证书)来加载证书和X509Certificate.GetPublicKey()
获得公共密钥。
对于迟到的反馈意见,但您的回答没有帮助。我没有从这个应用程序访问私钥,我的问题的核心是如何从PEM获得DER或ASN.1。 – 2011-07-14 23:06:31
要加载私钥让我们用这个代码:
private RSACryptoServiceProvider GetPrivateKey(string privateKey)
{
byte[] privkey = Convert.FromBase64String(privateKey);
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);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
CspParameters CspParameters = new CspParameters();
CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);
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 ex)
{
return null;
}
finally
{
binr.Close();
}
}
要加载公钥让我们用这个代码:
private RSACryptoServiceProvider GetPublicKey(string publicKeyString)
{
// encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
byte[] SeqOID = {0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00} ;
byte[] x509key;
byte[] seq = new byte[15];
int x509size;
x509key = Convert.FromBase64String(publicKeyString);
x509size = x509key.Length;
// --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------
MemoryStream mem = new MemoryStream(x509key);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 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;
seq = binr.ReadBytes(15); //read the Sequence OID
if (!CompareBytearrays(seq, SeqOID)) //make sure Sequence for OID is correct
return null;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8203)
binr.ReadInt16(); //advance 2 bytes
else
return null;
bt = binr.ReadByte();
if (bt != 0x00) //expect null byte next
return null;
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();
byte lowbyte = 0x00;
byte highbyte = 0x00;
if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus
else if (twobytes == 0x8202)
{
highbyte = binr.ReadByte(); //advance 2 bytes
lowbyte = binr.ReadByte();
}
else
return null;
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order
int modsize = BitConverter.ToInt32(modint, 0);
int firstbyte = binr.PeekChar();
if (firstbyte == 0x00)
{ //if first byte (highest order) of modulus is zero, don't include it
binr.ReadByte(); //skip this null byte
modsize -= 1; //reduce modulus buffer size by 1
}
byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes
if (binr.ReadByte() != 0x02) //expect an Integer for the exponent data
return null;
int expbytes = (int)binr.ReadByte(); // should only need one byte for actual exponent data (for all useful values)
byte[] exponent = binr.ReadBytes(expbytes);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAKeyInfo = new RSAParameters();
RSAKeyInfo.Modulus = modulus;
RSAKeyInfo.Exponent = exponent;
RSA.ImportParameters(RSAKeyInfo);
return RSA;
}
finally
{
binr.Close();
}
}
可以读取original post here获得更详细
我如何获得整数? – th1rdey3 2016-02-10 13:48:20
在[link](http:// langcongnghe。com/2014/11/10/tony/cach-thuc-doc-rsa-private-key-va-public-key-in-c.html) – 2016-04-17 15:52:03
任何运气有了这个?看到5个相同的问题,最接近的答案是pempublic.cs文件。仍然这个文件看起来有点乱。 – Devela 2014-01-27 06:40:25