RSA-JAVA与.NET公钥\私钥格式转换
使用c#进行RSA加密\解密时,公钥与私钥的格式与JAVA格式的不同,Java是很长的一串字符串,c#是XML格式。例如:
公钥:
<RSAKeyValue> <Modulus>pIpOkGhu0gJhsYHT9aRWgoOp6Gq0TUMrQXyTT1aEOM9epzrocuaaNDqX1VDwKNEgqvG1/1lrWP5IPOZdAFCFDgjBYC86niBUELTyqRvbuBSsWVyXn2ES33lJ1gwTA/ttlS+TOGJWtj9tLlCy5daqTLhnh86dVnEwRzcYeISQRxDATmrLXwfjvx/QlPxdKDEVL8Z+ppwOPCnFFSaq6ytV8chPWXkQzKEdF566NLMubMYTd6WTTG5Pvk5pD/7e90O6j8K0L/LwAUKaF+/KzLjqCKnurV9xlFg/Nc/o8QQCyXkOO6kcY7JfJi6jwmINdwuS2+DJYy+i7RLIlgQ+yWAG8w==</Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue>
私钥:
<RSAKeyValue>
<Modulus>pIpOkGhu0gJhsYHT9aRWgoOp6Gq0TUMrQXyTT1aEOM9epzrocuaaNDqX1VDwKNEgqvG1/1lrWP5IPOZdAFCFDgjBYC86niBUELTyqRvbuBSsWVyXn2ES33lJ1gwTA/ttlS+TOGJWtj9tLlCy5daqTLhnh86dVnEwRzcYeISQRxDATmrLXwfjvx/QlPxdKDEVL8Z+ppwOPCnFFSaq6ytV8chPWXkQzKEdF566NLMubMYTd6WTTG5Pvk5pD/7e90O6j8K0L/LwAUKaF+/KzLjqCKnurV9xlFg/Nc/o8QQCyXkOO6kcY7JfJi6jwmINdwuS2+DJYy+i7RLIlgQ+yWAG8w==</Modulus><Exponent>AQAB</Exponent>
<P>9k9GGSoGr0i1Lvqdh8BDHqlS23yU+3ePhu7U5nA3V0iKVIlqQL4S67kzYQ3aMuU752haTJ65Gw9XcMC4kidH3iBvIOj4iCtU069DAhle474uswP38alsA702/Sft+85RHusZpXtdDFGlnoXAGocvbpSWhUQQDMWzuAi5m78xouE=</P><Q>qwN8hngqbZpRHzkljpy1kAsaE+JhAv2w6HMGKTn6ocBowAc0ZG1s9fpeU1VKooPm6BIASFiZsfZPdeOUEA//BPpAr0mru9MBlXoyrOPz7/czGUyGz+sY0TiDtTJ7CdDk7ymGTL6PcfBonk2K/7bKV/47y/ze6j5E7lGvTYyHOFM=</Q>
<DP>OpTCJEwFiPzu8rxyaQ4GKK224jLwMBrQjRQSmLgJwX2kQNTp63oJf/ztRmEIC2DP7Yq5J0380n3EmzGK9F/ZTPBD3fzq12AO7cXaVw53rgzWiIciGlzkLsN655zukhwQ2RyrXdtIVxy4GkrPVL/gPRmj7xAwDQmcY+HXWz6O7KE=</DP>
<DQ>akTHW/ROQT+Uy3dCjGV7OeB8OwEA0c/93+SiXnoF8f/T2AhiGUoaXJxRgy1MLMMUeP++pzZPg9QQuqxJ9NVL3rb3/TUlf5j2sgF2fhNFIcgWO9FfMNLh4BljVvTgmk/yA2BlcUk1cFM5X63GA3N+N8HnPLKNfzhks0eVTPZXjLs=</DQ>
<InverseQ>3p0C9NhZsZpjMgKaJoDpVm/EJ+JcwZkzrwL1lTeOw4erXfjJP4Ww+cQX2OM44+LVjbxvaqv+43d6ftoS3AjZrGQifEVTP1vJobpGDPJnomAiu1KtS/q4ScwJ/WR4lP5ieXzPDMA1NFgGQ4ou1Ogwasw30Q5hPkQyErRfdPaHo5o=</InverseQ>
<D>GyHveKKv+5OG9pV5FV2nIliB0SCfYMo9vMvFIuUaYp/XdO4i3KeoMAqldPim0aRCpc27/EKLkB5GXTyDg4TDnB/Xe3vuR5r/Ic4k4bwFTGKkVQwOuKpySUWf5lsRW6u/U0WIGlklAWKOJ4AJMBto88PI1r08dr+tfWDZeS4q+HzG2CrQI5CrNCpEtLGUOfiv9ZE8Lk109pENn8ZM8LbuGjrnOa3C58wqFgKLvhWiGhZ3JLKUJAaoVLjSqd23ZNVV1ilqTSAG/2hhXUHnihjEf7E6cWRfwWjkcXLOEKG4M5re0JETUdYekp/BOZXoP7XuoPFw3/0YHBVCJeAkhdbmQQ==</D>
</RSAKeyValue>
转换格式需要引用 BouncyCastle.Crypto.dll
从Nuget下载BouncyCastle.Crypto.dll
需要引用以下的命名空间:
using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; using Org.BouncyCastle.X509;
互相转换的代码,都是固定写法:
/// <summary> /// RSA私钥格式转换,java->.net /// </summary> /// <param name="privateKey">java生成的RSA私钥</param> /// <returns></returns> public static string RSAPrivateKeyJavaToDotNet(string privateKey) { RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>", Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned())); } /// <summary> /// RSA公钥格式转换,java->.net /// </summary> /// <param name="publicKey">java生成的公钥</param> /// <returns></returns> public static string RSAPublicKeyJavaToDotNet(string publicKey) { RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>", Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned())); } /// <summary> /// RSA公钥格式转换,.net->java /// </summary> /// <param name="publicKey">.net生成的公钥</param> /// <returns></returns> public static string RSAPublicKeyDotNetToJava(string publicKey) { XmlDocument doc = new XmlDocument(); doc.LoadXml(publicKey); BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText)); BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText)); RsaKeyParameters pub = new RsaKeyParameters(false, m, p); SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub); byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded(); return Convert.ToBase64String(serializedPublicBytes); } /// <summary> /// RSA私钥格式转换,.net->java /// </summary> /// <param name="privateKey">.net生成的私钥</param> /// <returns></returns> public static string RSAPrivateKeyDotNetToJava(string privateKey) { XmlDocument doc = new XmlDocument(); doc.LoadXml(privateKey); BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText)); BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText)); BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText)); BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText)); BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText)); BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText)); BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText)); BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText)); RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv); PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam); byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded(); return Convert.ToBase64String(serializedPrivateBytes); }