在上文中了解到SHA和RSA,工作中恰好用到扩展应用:SHA256WithRSA,本文总结下学习过程,备忘の
再提供另外一种方法,实现Java版pem密钥和.Net版xml密钥相互转换的方法
- RSA密钥:Pem --> XML
public static string RSAKeyPemToXml(string pemKey, bool isPrivateKey)
{
string rsaKey = string.Empty;
object pemObject = null;
RSAParameters rsaPara = new RSAParameters();
using (var sReader = new StringReader(pemKey)) {
var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sReader);
pemObject = pemReader.ReadObject();//(AsymmetricCipherKeyPair)
}
if (isPrivateKey)//RSA私钥
{
RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)((AsymmetricCipherKeyPair)pemObject).Private;
rsaPara = new RSAParameters {
Modulus = key.Modulus.ToByteArrayUnsigned(),
Exponent = key.PublicExponent.ToByteArrayUnsigned(),
D = key.Exponent.ToByteArrayUnsigned(),
P = key.P.ToByteArrayUnsigned(),
Q = key.Q.ToByteArrayUnsigned(),
DP = key.DP.ToByteArrayUnsigned(),
DQ = key.DQ.ToByteArrayUnsigned(),
InverseQ = key.QInv.ToByteArrayUnsigned(), };
}
else//RSA公钥
{
RsaKeyParameters key = (RsaKeyParameters)pemObject;
rsaPara = new RSAParameters {
Modulus = key.Modulus.ToByteArrayUnsigned(),
Exponent = key.Exponent.ToByteArrayUnsigned(), };
}
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaPara);
using (StringWriter sw = new StringWriter()) {
sw.Write(rsa.ToXmlString(isPrivateKey ? true : false));
rsaKey = sw.ToString();
}
return rsaKey;
}
- RSA密钥:XML --> Pem
public static string RSAKeyXmlToPem(string RSAKeyXml, bool isPrivateKey, bool replacefix)
{
string pemKey = string.Empty;
var rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(RSAKeyXml);
RSAParameters rsaPara = new RSAParameters();
RsaKeyParameters key = null;
//RSA私钥
if (isPrivateKey) {
rsaPara = rsa.ExportParameters(true);
key = new RsaPrivateCrtKeyParameters(
new BigInteger(1, rsaPara.Modulus), new BigInteger(1, rsaPara.Exponent), new BigInteger(1, rsaPara.D),
new BigInteger(1, rsaPara.P), new BigInteger(1, rsaPara.Q), new BigInteger(1, rsaPara.DP), new BigInteger(1, rsaPara.DQ),
new BigInteger(1, rsaPara.InverseQ));
}
//RSA公钥
else {
rsaPara = rsa.ExportParameters(false);
key = new RsaKeyParameters(false,
new BigInteger(1, rsaPara.Modulus), new BigInteger(1, rsaPara.Exponent));
}
using (TextWriter sw = new StringWriter()) {
var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
pemWriter.WriteObject(key);
pemWriter.Writer.Flush();
pemKey = sw.ToString();
}
if (replacefix) {
//去掉证书的头部和尾部
pemKey = isPrivateKey ? pemKey.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "") :
pemKey.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
return pemKey.Replace("\n", "").Replace("\r", "");
}
else { return pemKey; }
}
注意,调用RSAKeyPemToXml()方法时,pemKey必须是格式正确的,否则调用报错。
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
扩展:从.pfx证书中提取公钥和私钥的方法
private static RSACryptoServiceProvider GetPrivateKey(string priKeyFile, string keyPwd) {
var pc = new X509Certificate2(priKeyFile, keyPwd,
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
return (RSACryptoServiceProvider)pc.PrivateKey; //return cert.PrivateKey.ToXmlString(true);
}
private static RSACryptoServiceProvider GetPublicKey(string pubKeyFile) {
var pc = new X509Certificate2(pubKeyFile);
return (RSACryptoServiceProvider)pc.PublicKey.Key; //return cert.PublicKey.Key.ToXmlString(false);
}