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


    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 加载私钥
    
    
            /// 
            /// 转换私钥字符串为RSACryptoServiceProvider
            /// 
            /// 私钥字符串
            /// PKCS8,PKCS1
            /// RSA 私钥长度1024 ,RSA2 私钥长度2048
            /// 
            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);
                }
            }
    
            /// 
            /// PKCS1 格式私钥转 RSACryptoServiceProvider 对象
            /// 
            /// pcsk1 私钥的文本内容
            /// RSA 私钥长度1024 ,RSA2 私钥长度2048 
            /// 
            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;
            }
    
            /// 
            /// PKCS8 文本转RSACryptoServiceProvider 对象
            /// 
            /// 
            /// 
            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;
                }
            }
    
            /// 
            /// PKCS8 私钥文本 转 .NET XML 私钥文本
            /// 
            /// 
            /// 
            public static string RSAPrivateKeyJava2DotNet(string privateKeyPemPkcs8)
            {
                RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyPemPkcs8));
                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())); } #endregion /// /// 加载公钥证书 /// /// 公钥证书文本内容 /// 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; } /// /// pem 公钥文本 转 .NET RSACryptoServiceProvider。 /// /// /// 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; } /// /// pem 公钥文本 转 .NET XML 公钥文本。 /// /// /// private 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())); } } }
    复制代码

     

    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 非标准的-私钥加密-公钥解密
    
            /// 
            /// 私钥加密 .Net平台默认是使用公钥进行加密,私钥进行解密。私钥加密需要自己实现或者使用第三方dll
            /// 
            /// 
            /// 私钥,格式:PKCS8
            /// 
            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;
    
            }
    
            /// 
            /// 私钥加密
            /// 
            /// 明文
            /// 私钥
            /// 私钥格式:PKCS1,PKCS8
            /// 
            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;
    
            }
    
            /// 
            /// RSA私钥格式转换,java->.net
            /// 
            /// 
            /// 
            private 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())); } /// /// 用公钥解密 /// /// /// /// 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; } /// /// RSA公钥格式转换,java->.net /// /// /// private 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())); } #endregion #region 标准的-公钥加密-私钥解密 /** 默认编码字符集 */ private static string DEFAULT_CHARSET = "UTF-8"; /// /// 公钥加密(超过 私钥长度 / 8 - 11,分段加密) /// /// 明文 /// 编码 /// 公钥 /// /// 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); } } /// /// 私钥解密(超过 私钥长度 / 8 - 11,分段加密) /// /// 密文 /// 编码 /// 私钥 /// 私钥格式 PKCS1,PKCS8 /// /// 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();
            }
        }
    }
    复制代码

     

    -

  • 相关阅读:
    中国设备维修安装企业能力等级证书(制冷空调)
    python爬虫和前端(部分)
    vscode自动升级后无法打开远程解决方案
    Python学习路线
    基于java+SpringBoot+HTML+Mysql线上视频购买学习
    C++ 模板和 C# 泛型之间的区别【示例语法说明】
    docker安装与部署
    【LeetCode】1154.一年中的第几天
    Qt之自定义model读写CSV文件
    在命令窗口便捷快速复制输出结果到剪贴板
  • 原文地址:https://www.cnblogs.com/runliuv/p/17468413.html