C#.NET Framework RSA 公钥加密 私钥解密 ver:20230609
阅读原文时间:2023年08月09日阅读:20

C#.NET Framework RSA 公钥加密 私钥解密 ver:20230609

环境说明:

.NET Framework 4.6 的控制台程序 。

.NET Framework 对于RSA的支持:

1. .NET Framework 内置只支持XML格式的私钥/公钥。如果要用PKCS1,PKCS8格式的,要用到三方库BouncyCastle。

2. .NET 中默认加密算法为“RSA/ECB/PKCS1Padding” ,要和JAVA互通,JAVA 那边也得是 RSA/ECB/PKCS1Padding 。

加密解析:

//假设私钥长度为1024, 1024/8-11=117。
//如果明文的长度小于117,直接全加密,然后转base64。(data.Length <= maxBlockSize) //如果明文长度大于117,则每117分一段加密,写入到另一个Stream中,最后转base64。while (blockSize > 0)

如果要和其它语言互通,这个分段长度需要和其它语言约定好,不一是 私钥长度/8-11。

解密解析:

//假设私钥长度为1024, 1024/8 =128。
//如果明文的长度小于 128,直接全解密。(data.Length <= maxBlockSize) //如果明文长度大于 128,则每 128 分一段解密,写入到另一个Stream中,最后 GetString。while (blockSize > 0)

用“支付宝开放平台开发助手”生成一组公私钥:

PKCS8私钥:

MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==

与之匹配的 PKCS1 私钥,用助手转换的:

MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=

与之匹配的公钥:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB

核心重点是拿到 .NET 的RSACryptoServiceProvider 对象。

nuget 中引用 Portable.BouncyCastle。

工具类:

RsaUtil 的作用: 将私钥(PKCS1,PKCS8)、公钥、私钥证书、公钥证书转为.NET RSACryptoServiceProvider 对象。

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace CommonUtils
{
///

/// 将私钥(PKCS1,PKCS8)、公钥、私钥证书、公钥证书转为.NET RSACryptoServiceProvider 对象 ///
public static class RsaUtil
{
#region 加载私钥

    /// <summary>  
    /// 转换私钥字符串为RSACryptoServiceProvider  
    /// </summary>  
    /// <param name="privateKeyStr">私钥字符串</param>  
    /// <param name="keyFormat">PKCS8,PKCS1</param>  
    /// <param name="signType">RSA 私钥长度1024 ,RSA2 私钥长度2048</param>  
    /// <returns></returns>  
    public static RSACryptoServiceProvider LoadPrivateKey(string privateKeyStr, string keyFormat)  
    {  
        string signType = "RSA";  
        if (privateKeyStr.Length > 1024)  
        {  
            signType = "RSA2";  
        }  
        //PKCS8,PKCS1  
        if (keyFormat == "PKCS1")  
        {  
            return LoadPrivateKeyPKCS1(privateKeyStr, signType);  
        }  
        else  
        {  
            return LoadPrivateKeyPKCS8(privateKeyStr);  
        }  
    }

    /// <summary>  
    /// PKCS1 格式私钥转 RSACryptoServiceProvider 对象  
    /// </summary>  
    /// <param name="strKey">pcsk1 私钥的文本内容</param>  
    /// <param name="signType">RSA 私钥长度1024 ,RSA2 私钥长度2048 </param>  
    /// <returns></returns>  
    public static RSACryptoServiceProvider LoadPrivateKeyPKCS1(string privateKeyPemPkcs1, string signType)  
    {  
        try  
        {  
            privateKeyPemPkcs1 = privateKeyPemPkcs1.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\\r", "").Replace("\\n", "").Trim();  
            privateKeyPemPkcs1 = privateKeyPemPkcs1.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\\r", "").Replace("\\n", "").Trim();

            byte\[\] data = null;  
            //读取带

            data = Convert.FromBase64String(privateKeyPemPkcs1);

            RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(data, signType);  
            return rsa;  
        }  
        catch (Exception ex)  
        {  
            throw ex;  
        }  
        return null;  
    }

    private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte\[\] privkey, string signType)  
    {  
        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);

            // ------- create RSACryptoServiceProvider instance and initialize with public key -----  
            CspParameters CspParameters = new CspParameters();  
            CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;

            int bitLen = 1024;  
            if ("RSA2".Equals(signType))  
            {  
                bitLen = 2048;  
            }

            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(bitLen, CspParameters);  
            //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 ex)  
        {  
            throw ex;  
            // return null;  
        }  
        finally  
        {  
            binr.Close();  
        }  
    }

    private static int GetIntegerSize(BinaryReader binr)  
    {  
        byte bt = 0;  
        byte lowbyte = 0x00;  
        byte highbyte = 0x00;  
        int count = 0;  
        bt = binr.ReadByte();  
        if (bt != 0x02)        //expect integer  
            return 0;  
        bt = binr.ReadByte();

        if (bt == 0x81)  
            count = binr.ReadByte();    // data size in next byte  
        else  
            if (bt == 0x82)  
        {  
            highbyte = binr.ReadByte(); // data size in next 2 bytes  
            lowbyte = binr.ReadByte();  
            byte\[\] modint = { lowbyte, highbyte, 0x00, 0x00 };  
            count = BitConverter.ToInt32(modint, 0);  
        }  
        else  
        {  
            count = bt;     // we already have the data size  
        }

        while (binr.ReadByte() == 0x00)  
        {    //remove high order zeros in data  
            count -= 1;  
        }  
        binr.BaseStream.Seek(-1, SeekOrigin.Current);        //last ReadByte wasn't a removed zero, so back up a byte  
        return count;  
    }

    /// <summary>  
    /// PKCS8 文本转RSACryptoServiceProvider 对象  
    /// </summary>  
    /// <param name="privateKeyPemPkcs8"></param>  
    /// <returns></returns>  
    public static RSACryptoServiceProvider LoadPrivateKeyPKCS8(string privateKeyPemPkcs8)  
    {

        try  
        {  
            //PKCS8是“BEGIN PRIVATE KEY”  
            privateKeyPemPkcs8 = privateKeyPemPkcs8.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\\r", "").Replace("\\n", "").Trim();  
            privateKeyPemPkcs8 = privateKeyPemPkcs8.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\\r", "").Replace("\\n", "").Trim();

            //pkcs8 文本先转为 .NET XML 私钥字符串  
            string privateKeyXml = RSAPrivateKeyJava2DotNet(privateKeyPemPkcs8);

            RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();  
            publicRsa.FromXmlString(privateKeyXml);  
            return publicRsa;  
        }  
        catch (Exception ex)  
        {  
            throw ex;  
        }  
    }

    /// <summary>  
    /// PKCS8 私钥文本 转 .NET XML 私钥文本  
    /// </summary>  
    /// <param name="privateKeyPemPkcs8"></param>  
    /// <returns></returns>  
    public static string RSAPrivateKeyJava2DotNet(string privateKeyPemPkcs8)  
    {  
        RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyPemPkcs8));  
        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()));  
    }

    #endregion

    /// <summary>  
    /// 加载公钥证书  
    /// </summary>  
    /// <param name="publicKeyCert">公钥证书文本内容</param>  
    /// <returns></returns>  
    public static RSACryptoServiceProvider LoadPublicCert(string publicKeyCert)  
    {

        publicKeyCert = publicKeyCert.Replace("-----BEGIN CERTIFICATE-----", "").Replace("-----END CERTIFICATE-----", "").Replace("\\r", "").Replace("\\n", "").Trim();

        byte\[\] bytesCerContent = Convert.FromBase64String(publicKeyCert);  
        X509Certificate2 x509 = new X509Certificate2(bytesCerContent);  
        RSACryptoServiceProvider rsaPub = (RSACryptoServiceProvider)x509.PublicKey.Key;  
        return rsaPub;

    }

    /// <summary>  
    /// pem 公钥文本 转  .NET RSACryptoServiceProvider。  
    /// </summary>  
    /// <param name="publicKeyPem"></param>  
    /// <returns></returns>  
    public static RSACryptoServiceProvider LoadPublicKey(string publicKeyPem)  
    {

        publicKeyPem = publicKeyPem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\\r", "").Replace("\\n", "").Trim();

        //pem 公钥文本 转  .NET XML 公钥文本。  
        string publicKeyXml = RSAPublicKeyJava2DotNet(publicKeyPem);

        RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();  
        publicRsa.FromXmlString(publicKeyXml);  
        return publicRsa;

    }

    /// <summary>  
    /// pem 公钥文本 转  .NET XML 公钥文本。  
    /// </summary>  
    /// <param name="publicKey"></param>  
    /// <returns></returns>  
    private static string RSAPublicKeyJava2DotNet(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()));  
    }

}  

}

RsaEncryptUtil 工具类:基于 RSACryptoServiceProvider 加密解密的轻度封装,标准的支持分段加密。

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace CommonUtils
{
///

/// 基于 RSACryptoServiceProvider 加密解密的轻度封装,标准的支持分段加密。 ///
public static class RsaEncryptUtil
{

    #region 非标准的-私钥加密-公钥解密

    /// <summary>  
    /// 私钥加密 .Net平台默认是使用公钥进行加密,私钥进行解密。私钥加密需要自己实现或者使用第三方dll  
    /// </summary>  
    /// <param name="data"></param>  
    /// <param name="key">私钥,格式:PKCS8</param>  
    /// <returns></returns>  
    public static byte\[\] encryptByPrivateKey(String data, String key)  
    {  
        String priKey = key.Trim();  
        String xmlPrivateKey = RSAPrivateKeyJava2DotNet(priKey);  
        //加载私钥  
        RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();  
        privateRsa.FromXmlString(xmlPrivateKey);  
        //转换密钥  
        AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);  
        IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致  
        c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥  
        byte\[\] DataToEncrypt = Encoding.UTF8.GetBytes(data);  
        byte\[\] outBytes = c.DoFinal(DataToEncrypt);//加密  
        return outBytes;

    }

    /// <summary>  
    /// 私钥加密  
    /// </summary>  
    /// <param name="data">明文</param>  
    /// <param name="key">私钥</param>  
    /// <param name="keyFormat">私钥格式:PKCS1,PKCS8</param>  
    /// <returns></returns>  
    public static byte\[\] encryptByPrivateKey(String data, String key, string keyFormat)  
    {  
        String priKey = key.Trim();

        //加载私钥  
        RSACryptoServiceProvider privateRsa = RsaUtil.LoadPrivateKey(key, keyFormat);

        //转换密钥  
        AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);  
        IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致  
        c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥  
        byte\[\] DataToEncrypt = Encoding.UTF8.GetBytes(data);  
        byte\[\] outBytes = c.DoFinal(DataToEncrypt);//加密  
        return outBytes;

    }

    /// <summary>  
    /// RSA私钥格式转换,java->.net  
    /// </summary>  
    /// <param name="privateKey"></param>  
    /// <returns></returns>  
    private static string RSAPrivateKeyJava2DotNet(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>  
    /// 用公钥解密  
    /// </summary>  
    /// <param name="data"></param>  
    /// <param name="key"></param>  
    /// <returns></returns>  
    public static byte\[\] decryptByPublicKey(String data, String key)  
    {  
        String pubKey = key.Trim();  
        String xmlPublicKey = RSAPublicKeyJava2DotNet(pubKey);

        RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();  
        publicRsa.FromXmlString(xmlPublicKey);

        AsymmetricKeyParameter keyPair = DotNetUtilities.GetRsaPublicKey(publicRsa);  
        //转换密钥  
        // AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(publicRsa);  
        IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致  
        c.Init(false, keyPair); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥  
        byte\[\] DataToEncrypt = Convert.FromBase64String(data);  
        byte\[\] outBytes = c.DoFinal(DataToEncrypt);//解密  
        return outBytes;  
    }

    /// <summary>  
    /// RSA公钥格式转换,java->.net  
    /// </summary>  
    /// <param name="publicKey"></param>  
    /// <returns></returns>  
    private static string RSAPublicKeyJava2DotNet(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()));  
    }

    #endregion

    #region 标准的-公钥加密-私钥解密

    /\*\* 默认编码字符集 \*/  
    private static string DEFAULT\_CHARSET = "UTF-8";

    /// <summary>  
    /// 公钥加密(超过 私钥长度 / 8 - 11,分段加密)  
    /// </summary>  
    /// <param name="content">明文</param>  
    /// <param name="charset">编码</param>  
    /// <param name="publicKeyPem">公钥</param>  
    /// <returns></returns>  
    /// <exception cref="Exception"></exception>  
    public static string RSAEncrypt(string content, string charset, string publicKeyPem)  
    {  
        try  
        {  
            //假设私钥长度为1024, 1024/8-11=117。  
            //如果明文的长度小于117,直接全加密,然后转base64。(data.Length <= maxBlockSize)  
            //如果明文长度大于117,则每117分一段加密,写入到另一个Stream中,最后转base64。while (blockSize > 0)

            RSACryptoServiceProvider rsa = RsaUtil.LoadPublicKey(publicKeyPem);  
            //string sPublicKeyPEM = File.ReadAllText(publicKeyPem);  
            //RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();  
            //rsa.PersistKeyInCsp = false;  
            //RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);  
            if (string.IsNullOrEmpty(charset))  
            {  
                charset = DEFAULT\_CHARSET;  
            }  
            byte\[\] data = Encoding.GetEncoding(charset).GetBytes(content);  
            int maxBlockSize = rsa.KeySize / 8 - 11; //加密块最大长度限制  
            if (data.Length <= maxBlockSize)  
            {  
                byte\[\] cipherbytes = rsa.Encrypt(data, false);  
                return Convert.ToBase64String(cipherbytes);  
            }  
            MemoryStream plaiStream = new MemoryStream(data);  
            MemoryStream crypStream = new MemoryStream();  
            Byte\[\] buffer = new Byte\[maxBlockSize\];  
            int blockSize = plaiStream.Read(buffer, 0, maxBlockSize);  
            while (blockSize > 0)  
            {  
                Byte\[\] toEncrypt = new Byte\[blockSize\];  
                Array.Copy(buffer, 0, toEncrypt, 0, blockSize);  
                Byte\[\] cryptograph = rsa.Encrypt(toEncrypt, false);  
                crypStream.Write(cryptograph, 0, cryptograph.Length);  
                blockSize = plaiStream.Read(buffer, 0, maxBlockSize);  
            }

            return Convert.ToBase64String(crypStream.ToArray(), Base64FormattingOptions.None);  
        }  
        catch (Exception ex)  
        {  
            throw new Exception("EncryptContent = " + content + ",charset = " + charset, ex);  
        }  
    }

    /// <summary>  
    /// 私钥解密(超过 私钥长度 / 8 - 11,分段加密)  
    /// </summary>  
    /// <param name="content">密文</param>  
    /// <param name="charset">编码</param>  
    /// <param name="privateKeyPem">私钥</param>  
    /// <param name="keyFormat">私钥格式 PKCS1,PKCS8</param>  
    /// <returns></returns>  
    /// <exception cref="Exception"></exception>  
    public static string RSADecrypt(string content, string charset, string privateKeyPem, string keyFormat)  
    {  
        try  
        {  
            //假设私钥长度为1024, 1024/8 =128。  
            //如果明文的长度小于 128,直接全解密。(data.Length <= maxBlockSize)  
            //如果明文长度大于 128,则每 128 分一段解密,写入到另一个Stream中,最后 GetString。while (blockSize > 0)

            RSACryptoServiceProvider rsaCsp = RsaUtil.LoadPrivateKey(privateKeyPem, keyFormat);

            //RSACryptoServiceProvider rsaCsp = LoadCertificateFile(privateKeyPem, signType);  
            if (string.IsNullOrEmpty(charset))  
            {  
                charset = DEFAULT\_CHARSET;  
            }  
            byte\[\] data = Convert.FromBase64String(content);  
            int maxBlockSize = rsaCsp.KeySize / 8; //解密块最大长度限制  
            if (data.Length <= maxBlockSize)  
            {  
                byte\[\] cipherbytes = rsaCsp.Decrypt(data, false);  
                return Encoding.GetEncoding(charset).GetString(cipherbytes);  
            }  
            MemoryStream crypStream = new MemoryStream(data);  
            MemoryStream plaiStream = new MemoryStream();  
            Byte\[\] buffer = new Byte\[maxBlockSize\];  
            int blockSize = crypStream.Read(buffer, 0, maxBlockSize);  
            while (blockSize > 0)  
            {  
                Byte\[\] toDecrypt = new Byte\[blockSize\];  
                Array.Copy(buffer, 0, toDecrypt, 0, blockSize);  
                Byte\[\] cryptograph = rsaCsp.Decrypt(toDecrypt, false);  
                plaiStream.Write(cryptograph, 0, cryptograph.Length);  
                blockSize = crypStream.Read(buffer, 0, maxBlockSize);  
            }

            return Encoding.GetEncoding(charset).GetString(plaiStream.ToArray());  
        }  
        catch (Exception ex)  
        {  
            throw new Exception("DecryptContent = " + content + ",charset = " + charset, ex);  
        }  
    }

    #endregion

}  

}

调用示例:

using CommonUtils;
using System;

namespace ConsoleNetFxRsaEncrypt
{
class Program
{
static void Main(string[] args)
{
try
{
//PKCS8格式私钥
string strPriPkcs8 = "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==";
//PKCS1格式私钥
string strPriPkcs1 = "MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=";
//公钥
string strPub = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB";

            string strDJM = "泰酷拉!123ABC";//待加密字符串  
            strDJM = "泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC";//待加密字符串,超过117字符的测试

            Console.WriteLine("待加密字符串:" + strDJM);  
            string charSet = "UTF-8";  
            string strJMH = RsaEncryptUtil.RSAEncrypt(strDJM, charSet, strPub);//密文  
            Console.WriteLine("密文:" + strJMH);

            string strDecryptedByPkcs8 = RsaEncryptUtil.RSADecrypt(strJMH, charSet, strPriPkcs8, "PKCS8");//使用PKCS8格式私钥解密  
            Console.WriteLine("PKCS8 解密后:" + strDecryptedByPkcs8);

            string strDecryptedByPkcs1 = RsaEncryptUtil.RSADecrypt(strJMH, charSet, strPriPkcs1, "PKCS1");//使用PKCS1格式私钥解密

            Console.WriteLine("PKCS1 解密后:" + strDecryptedByPkcs1);

        }  
        catch (Exception ex)  
        {  
            Console.WriteLine("ex:" + ex.Message);  
        }

        Console.WriteLine("hello");  
        Console.ReadKey();  
    }  
}  

}

-