C#实现RSA加密解密、加签验签
一、密钥格式:
1、pem格式
私钥:
-----BEGIN PRIVATE KEY----- MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANfaT19X5NevSwjD +gYj2/aD42YOt/Xpx18rjmg8TIQYfSypxi+9NOMPaKi8eW04wKJ2BXZMf5LRshvo kSg9pbv/7Jq1ff4y8ekKc7KVoMfloo0qjL8nJGf9zL1NcCTRAsCUpMKd8/UDezla pEM7Z/oHvSuKZ9+n2B+z9JVWGPLTAgMBAAECgYEAjn9nwNikkaL+lRXTvDP2JaLh /2EeHvErlm+JvtR36wjDsjWOSbvN60wj2qk6PFmoCliBuJw96C4ZOAVrtrYj72cy WvCg302y8Ugc8JjSuQMaDFck5jAD1rWt4IyZnHgogjryOAZ8KTl8kfAqCWIPS2BS xIWZojhphn/vWkCYMWECQQDzLOgEF7mGUtx14B9ezJ2DS+iKV6k5lSWTGO4AqZ1g T+lOLiNo5PuDMxSTMvuUQVULda4Su0EI4zqmlcr7C3axAkEA4zyF0YAdPWjNTy+s ezQ5NpZuj5K9A2xAAu0Y1vp8bJGSt8oZdGewtL/QHSylJbG+xKiMRo5g9xwkkx0W M0yqwwJBALVF5ncWkHA3WKxuNDRg55I2hdSK4FVSfz4WOWU5C13+c/aZoj/RYkQ9 UbshKDUuNo1iXi8Mc8CCUvhXdYaK1yECQHCxtVP/C4FHFnstE4dOkQlHdbFyfpbR +rT4zRbgxxA46eCINDOMsRATCK1PVN/q1MdHJ7peJiynImRrSnVKkm0CQQCpmnAg UnByBn4BJBgA26WRx/ag2S4gEU9TMnW+vMPFfscMvzMuOy34phlQqbHyniHi9Y5r i7mELpNVp45VGi0l -----END PRIVATE KEY-----
公钥:
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDX2k9fV+TXr0sIw/oGI9v2g+Nm Drf16cdfK45oPEyEGH0sqcYvvTTjD2iovHltOMCidgV2TH+S0bIb6JEoPaW7/+ya tX3+MvHpCnOylaDH5aKNKoy/JyRn/cy9TXAk0QLAlKTCnfP1A3s5WqRDO2f6B70r imffp9gfs/SVVhjy0wIDAQAB -----END PUBLIC KEY-----
2、xml格式(c#默认)
私钥:
riLSQFVDC229P5F+Mkicbkpg5OC8+SeL6hvkJXIGYiN/e4YnprCxuIp5sH9AwWup4WJmObPKd1jOVGm07UwgVU7CDtTaVe1Uuk78yJBwgRuSteQjHYMmH6nG5YHvvONuvkmLnyIKGygJBL+4+Qmd3GaCHRtIrdfShlH3UbPINlM= AQAB 6yCboYtKzIezMOFzGzzW8dp7SBT8f7jTRzH1ZIKQYKF0Mq/39k80SeUvY578O031+bg6i3cbNvvAhL8XjqTtmQ==
vZgnL5LHnNE5uUW5NBwYvZbIz6hWNzc6kyDGimI8WBBFJOI06IdYGL2VMeGVs4lt5a1tM7T3c6gzBKgDQpL+yw==p5tV9YDyr/unq5d6Uxc6bar9qHN1TqJ00VJ2h9BelNNinmM70fPB5U8fSddiG/BGAF3oNdSQrNAm+zmw1DkTOQ== fxS1b1XbJmm3X1A0y5DppGqlP0t+PpRuVp/pdGhUOlLthcN540KU8kBg+IZUaXr8hq6wO7BZDNT5HW3ggYc18Q== q29etXnlszOH0FlQWDL9yLfJ+EruH4VURY1mZGz/+/qvPewUwyEf+EqJkZHVXEijnSa1CiFELK2YE9PhkUp2Xw== bZUoLqf5KwYCJDDQ85/SIW3ZD++FvF1wpQCsUAwzjCq+nONNrI5hKLqr3bAW9iFkpJshrYpBDV3rah+jZfmUFk/UZeur2+kA2r5r1or34+HiIhT4sehU1lxww4DvTzf1/1ivG4LCvUPoFtT67Zdh8pNEC27N6bFDL8fbSU7GcmE=
公钥:
riLSQFVDC229P5F+Mkicbkpg5OC8+SeL6hvkJXIGYiN/e4YnprCxuIp5sH9AwWup4WJmObPKd1jOVGm07UwgVU7CDtTaVe1Uuk78yJBwgRuSteQjHYMmH6nG5YHvvONuvkmLnyIKGygJBL+4+Qmd3GaCHRtIrdfShlH3UbPINlM= AQAB
3、ASN格式(java)
公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoUK4y6LX1kiHu0ubO1C1wRBrcgdSXBwI4CRuKK1fpTsS2dHpB5V+wQ63Rts3Ohr0E+pqIlaFu77Kp/UTczTH5dzSi4vdsexCBSnqC9RZLftadskTlf7OlHrF9Emva3s7Yla73EY56Jb0E/CS/PjKuNDNZ2CoZc2c3YBHDtObvhQIDAQAB
私钥:
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOhQrjLotfWSIe7S5s7ULXBEGtyB1JcHAjgJG4orV+lOxLZ0ekHlX7BDrdG2zc6GvQT6moiVoW7vsqn9RNzNMfl3NKLi92x7EIFKeoL1Fkt+1p2yROV/s6UesX0Sa9reztiVrvcRjnolvQT8JL8+Mq40M1nYKhlzZzdgEcO05u+FAgMBAAECgYByqsAQ6MRHfeW51+eM1zXGYBdSF9My6Iaz2er5/ALcacC2vi9KL0lX21AEX1KeSesqdfeoyxJvi2iIdzZyNeYf52JUvvhnwedDu7YKi6xFgjvBbCPmifbau/r3JELQDHqRbnpYIe1NLrz9D0QBST5skGrYmeQe9NvVKEMMFuwPAQJBAPnTQI4AArADapYQjQnIE2Z94f1sAFkmvuI0kHikXFJKZ+CSWLw+vYrRkV1ct+Am2nz244e1AIcVG/iteYMs13UCQQDuDqKNFT43crjquJt3EzQWLxvQaK+bIKGVjcWje2xSH5oCiyPCk2RhWjd46aSPViPwyn5RPjsy0+EwLrm7xsXRAkAVbVYLF9sjJ5fbuR2vqhZn4wIgD0RUYStcEXAWuNomQLV6IHM16hetsV3LaSloM0zoDPDk8dRSwa+9e3uBkbYFAkAFOw0XTIAxd7PYdHX2B9X9JsvVqHczUWQ7hQHytaOLqmYX6DbA77wk53aQkZGsFJh1kf10i4mBdGZeSKiMF7IBAkAhniFbHF4G0RKxCJ3paII0m7qn3eI+pIPEGFX3sZjMYaYtWV9WmbvxytSdv88pa1Mh/ZxZjZTjsp0cq+XffD3r
4、DER格式:
直接对二进制密钥进行binToHex后得到的密钥格式,密钥格式如下:
公钥:
30818902818100C19CFA5EA25F99C482499E3A557C7D0C3ABB375B19900CF4956E39F5B1EACA46A37CEE30DDBEA72979B6DABA11D4B9BD51CB1D79ED667607E65CF53491EE6BE35155072D5EFB96BA0E0FC0B9C1DFEDFA30886F645218CC680E55A7D5568AD59283E9BB3DC82970F6B3F6DD83FB308E2C610F362C71977D428614ED5FB59EFDB10203010001
私钥:
3082025D020100028181009951BFB322876658587C207F2AFC2F2638DFD4EEEE925669C4A9487A3774891AEBE638940318B1AE270784FCFBE768C8C989E33B3953D820326DFAC7862AA133F96EE216C1B3F5651D45194CA02E9926E8FF133B2C03BB22BFE8C60B13D4757F263D4A792B188A8183FAB53B193C8AF8AB8EAB7020547C20D5BC90E1B369DBA902030100010281800FD9829ECB28022D89E0331FD25AC5A906E224CA1A81A84B40D85B34BF3CDDDB999D7025E4F80D8E3A5CADA3D58AC3AB56225A0A4A4FDF9CDC79C01E16419BEE71997546C68E6408E5D9C044858DCB6393F285D3EBAAD0C75298F61B33B752EB8E1ABA4D66E5380FF52DE07929A96367673CDAE5945A0C13F3503FABEDB1758D024100C52F9745C13B77968D52F29ACDEE00F2DF07AF8025048348B054B7EFF460097CAB824212447F674B55CF74E489DD399E702D3D655C74484248E05CA2E9DCCEE7024100C70CA9EA361ED73C42627254F33A3FA81AD0AADD64D45A1E536E64C7E31737B7ED3FCC20E03A082673C6E7A7270640F6132AA295FF406D6133090E7D89397EEF024100883505936395065872AAB77683854216824536CF97C2744543B8618E5909F5C3AE5D3DF28C6A4D19D6DE84EA50E905A211EECE18343306AEF2D43869388E1445024100B061FE6776D1D974A276CE4D8CC2FF099DC96EBF84CBCF97B3E2CD177B9A655B6CB6EDD1EC20407CA2778D6B475F794D152AE0ABFE663F06B4CCBFB46A5732AD02404981E8728E85719A319C9A8C4C7D3B162BFA728AD5FD054C0A45A9A625385167F0822D2398680FD75BF29A3C20A4D72D2115ABD06F27B3819214AAC77284518A
二、代码
公钥加密:
////// RSA加密 /// /// /// /// /// public static string EncryptCSharp(string publicKeyCSharp, string data, string encoding = "UTF-8") { if(string.IsNullOrEmpty(data)) { return string.Empty; } if(string.IsNullOrWhiteSpace(publicKeyCSharp)) { throw new ArgumentException("Invalid Public Key"); } using(var rsa = new RSACryptoServiceProvider()) { var inputBytes = Encoding.GetEncoding(encoding).GetBytes(data); //有含义的字符串转化为字节流 rsa.FromXmlString(publicKeyCSharp); //载入公钥 int bufferSize = (rsa.KeySize / 8) - 11; //单块最大长度 var buffer = new byte[bufferSize]; using(MemoryStream inputStream = new MemoryStream(inputBytes), outputStream = new MemoryStream()) { while(true) { //分段加密 int readSize = inputStream.Read(buffer, 0, bufferSize); if(readSize <= 0) { break; } var temp = new byte[readSize]; Array.Copy(buffer, 0, temp, 0, readSize); var encryptedBytes = rsa.Encrypt(temp, false); outputStream.Write(encryptedBytes, 0, encryptedBytes.Length); } return Convert.ToBase64String(outputStream.ToArray()); //转化为字节流方便传输 } } }
私钥解密:
////// RSA解密 /// /// /// /// /// public static string DecryptCSharp(string privateKeyCSharp, string data, string encoding = "UTF-8") { if(string.IsNullOrEmpty(data)) { return string.Empty; } if(string.IsNullOrWhiteSpace(privateKeyCSharp)) { throw new ArgumentException("Invalid Private Key"); } using(var rsa = new RSACryptoServiceProvider()) { var inputBytes = Convert.FromBase64String(data); rsa.FromXmlString(privateKeyCSharp); int bufferSize = rsa.KeySize / 8; var buffer = new byte[bufferSize]; using(MemoryStream inputStream = new MemoryStream(inputBytes), outputStream = new MemoryStream()) { while(true) { int readSize = inputStream.Read(buffer, 0, bufferSize); if(readSize <= 0) { break; } var temp = new byte[readSize]; Array.Copy(buffer, 0, temp, 0, readSize); var rawBytes = rsa.Decrypt(temp, false); outputStream.Write(rawBytes, 0, rawBytes.Length); } return Encoding.GetEncoding(encoding).GetString(outputStream.ToArray()); } } }
私钥加签:
////// RSA签名CSharp /// /// 私钥 /// 待签名的内容 /// public static string RSASignCSharp(string data, string privateKeyCSharp, string hashAlgorithm = "MD5", string encoding = "UTF-8") { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(privateKeyCSharp); //加载私钥 var dataBytes = Encoding.GetEncoding(encoding).GetBytes(data); var HashbyteSignature = rsa.SignData(dataBytes, hashAlgorithm); return Convert.ToBase64String(HashbyteSignature); }
公钥验签:
////// 验证签名CSharp /// /// /// /// /// public static bool VerifyCSharp(string data, string publicKeyCSharp, string signature, string hashAlgorithm = "MD5", string encoding = "UTF-8") { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); //导入公钥,准备验证签名 rsa.FromXmlString(publicKeyCSharp); //返回数据验证结果 byte[] Data = Encoding.GetEncoding(encoding).GetBytes(data); byte[] rgbSignature = Convert.FromBase64String(signature); return rsa.VerifyData(Data, hashAlgorithm, rgbSignature); }
公钥转换:
////// RSA公钥格式转换,java->.net /// /// java生成的公钥 /// public static string RSAPublicKeyJava2DotNet(string publicKey) { RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)); return string.Format(" ", Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned())); } {0} {1}
私钥转换:
////// RSA私钥格式转换,java->.net /// /// java生成的私钥 /// public static string RSAPrivateKeyJava2DotNet(string privateKey) { RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); return string.Format(" ", 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())); } {0} {1} {2}
{3}{4} {5} {6} {7}
调用代码:
string encryptStr = EncryptCSharp(PubKey, data, "utf-8");//公钥加密 string decryptStr = DecryptCSharp(PriKey, data);//私钥解密 string sign = RSASignCSharp(signData, PriKey, "SHA1");//私钥加签 bool flag = VerifyCSharp(signData, PubKey, sign, "SHA1");//公钥验签
加签验签时要注意hashAlgorithm的写法,java中的“SHA1WithRSA”对应c#的“SHA1”,hashAlgorithm包括{ "MD5", "SHA1", "SHA256", "SHA384", "SHA512" }