我有格式的RSA
私钥PEM
,是否有直接的方式从.NET读取并实例化RSACryptoServiceProvider
解密用相应的公钥加密的数据?
我解决了,谢谢.如果有人感兴趣,bouncycastle就是这样做的,只是花了一些时间,因为我缺乏知识和文档.这是代码:
var bytesToDecrypt = Convert.FromBase64String("la0Cz.....D43g=="); // string to decrypt, base64 encoded AsymmetricCipherKeyPair keyPair; using (var reader = File.OpenText(@"c:\myprivatekey.pem")) // file containing RSA PKCS1 private key keyPair = (AsymmetricCipherKeyPair) new PemReader(reader).ReadObject(); var decryptEngine = new Pkcs1Encoding(new RsaEngine()); decryptEngine.Init(false, keyPair.Private); var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
关于轻松导入RSA私钥,不使用BouncyCastle等第三方代码,我认为答案是"不,不是单独使用私钥的PEM".
但是,正如Simone所提到的,您可以简单地将私钥(*.key)的PEM和使用该密钥(*.crt)的证书文件组合成*.pfx文件,然后可以轻松导入该文件.
要从命令行生成PFX文件:
openssl pkcs12 -in a.crt -inkey a.key -export -out a.pfx
然后正常使用.NET证书类,例如:
using System.Security.Cryptography.X509Certificates; X509Certificate2 combinedCertificate = new X509Certificate2(@"C:\path\to\file.pfx");
现在,您可以按照MSDN中的示例通过RSACryptoServiceProvider进行加密和解密:
我遗漏了解密,你需要使用PFX密码和Exportable标志导入.(参见:BouncyCastle RSAPrivateKey到.NET RSAPrivateKey)
X509KeyStorageFlags flags = X509KeyStorageFlags.Exportable; X509Certificate2 cert = new X509Certificate2("my.pfx", "somepass", flags); RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey; RSAParameters rsaParam = rsa.ExportParameters(true);
您可以查看JavaScience的OpenSSLKey源代码.(OpenSSLKey.cs)
那里的代码完全符合您的要求.
事实上,他们有很多的加密源代码可在这里.
源代码片段:
//------- 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(); } }