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("{0}{1}",
                Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
                Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));

        }

 私钥转换:

        /// 
        /// RSA私钥格式转换,java->.net
        /// 
        /// java生成的私钥
        /// 
        public static string RSAPrivateKeyJava2DotNet(string privateKey)
        {
            RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));

            return string.Format("{0}{1}

{2}

{3}{4}{5}{6}{7}
", 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())); }

调用代码:

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" }

相关