RSA公钥加密

2024-08-28  本文已影响0人  sttone
using System;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Encodings;
using System.IO;

namespace v4_RSAHelper
{
    public  class BCSignUtil
    {
        /// <summary>
        /// 签名
        /// </summary>
        /// <param name="orgData">原数据字符串</param>
        /// <param name="privateKeyPKCS8">必须是PKCS8的</param>
        /// <param name="algorithm">算法</param>
        /// <returns></returns>
        public static string SignData(string orgData, string privateKeyPKCS8, string algorithm)
        {
            if (string.IsNullOrEmpty(orgData))
                throw new Exception("字符串不能为空!");

            if (string.IsNullOrEmpty(privateKeyPKCS8))
                throw new Exception("privateKeyPKCS8不能为空!");

            if (string.IsNullOrEmpty(privateKeyPKCS8))
                throw new Exception("algorithm 不能为空!");

            AsymmetricKeyParameter priKey = GetPrivateKeyParameter(privateKeyPKCS8);

            byte[] byteData = Encoding.UTF8.GetBytes(orgData);

            ISigner normalSig = SignerUtilities.GetSigner(algorithm);
            normalSig.Init(true, priKey);
            normalSig.BlockUpdate(byteData, 0, byteData.Length);//注意:是byte数组和数组长度,别写成string的长度了
            byte[] normalResult = normalSig.GenerateSignature(); //签名结果
            string sign = Convert.ToBase64String(normalResult);

            return sign;
        }

        private static AsymmetricKeyParameter GetPrivateKeyParameter(string privateKeyPem)
        {
            //获取私钥纯字符串
            privateKeyPem = privateKeyPem.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
            privateKeyPem = privateKeyPem.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();

            byte[] privateInfoByte = Convert.FromBase64String(privateKeyPem);

            AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
            return priKey;
        }

        /// <summary>
        /// 验证签名
        /// </summary>
        /// <param name="orgData">原数据字符串</param>
        /// <param name="publicKeyPem">公钥</param>
        /// <param name="responseSign">对方的签名串</param>
        /// <param name="algorithm">算法</param>
        /// <returns></returns>
        public static bool VerifySignature(string orgData, string publicKeyPem, string responseSign, string algorithm)
        {

            AsymmetricKeyParameter pubKey = GetPublicKeyParameter(publicKeyPem);


            byte[] signBytes = Convert.FromBase64String(responseSign);
            byte[] plainBytes = Encoding.UTF8.GetBytes(orgData);

            ISigner verifier = SignerUtilities.GetSigner(algorithm);
            verifier.Init(false, pubKey);
            verifier.BlockUpdate(plainBytes, 0, plainBytes.Length);//注意:是byte数组和数组长度,别写成string的长度了

            bool isOK = verifier.VerifySignature(signBytes); //验签结果
            return isOK;
        }

        private static AsymmetricKeyParameter GetPublicKeyParameter(string publicKeyPem)
        {
            //获取公钥纯字符串
            publicKeyPem = publicKeyPem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();

            byte[] publicInfoByte = Convert.FromBase64String(publicKeyPem);

            AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
            return pubKey;
        }

        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="orgData">数据</param>
        /// <param name="key">私钥、公钥</param>
        /// <param name="isPublicKey">是否为公钥</param>
        /// <param name="privateKeySize">私钥长度,一般是1024或2048</param>
        /// <returns></returns>
        public static string EncryptByKey(string orgData, string key, bool isPublicKey, int privateKeySize)
        {
            //非对称加密算法,加解密用  
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
            //加密  

            //1024长度是117,双方协商好
            int maxBlockSize = privateKeySize / 8 - 11; //加密块最大长度限制

            engine.Init(true, isPublicKey ? GetPublicKeyParameter(key) : GetPrivateKeyParameter(key));
            byte[] byteData = System.Text.Encoding.UTF8.GetBytes(orgData);

            int inputLen = byteData.Length;
            MemoryStream ms = new MemoryStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密
            while (inputLen - offSet > 0)
            {
                if (inputLen - offSet > maxBlockSize)
                {
                    cache = engine.ProcessBlock(byteData, offSet, maxBlockSize);
                }
                else
                {
                    cache = engine.ProcessBlock(byteData, offSet, inputLen - offSet);
                }
                ms.Write(cache, 0, cache.Length);
                i++;
                offSet = i * maxBlockSize;
            }
            byte[] encryptedData = ms.ToArray();

            //var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
            return Convert.ToBase64String(encryptedData);
            //Console.WriteLine("密文(base64编码):" + Convert.ToBase64String(testData) + Environment.NewLine);

        }
        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="orgData">数据</param>
        /// <param name="key">私钥、公钥</param>
        /// <param name="isPublicKey">是否为公钥</param>
        /// <param name="privateKeySize">私钥长度,一般是1024或2048</param>
        /// <returns></returns>
        public static string DecryptByKey(string orgData, string key, bool isPublicKey, int privateKeySize)
        {
            orgData = orgData.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            //非对称加密算法,加解密用  
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());


            //解密  


            //1024长度是128,双方协商好
            int maxBlockSize = privateKeySize / 8; //解密块最大长度限制

            engine.Init(false, isPublicKey ? GetPublicKeyParameter(key) : GetPrivateKeyParameter(key));
            byte[] byteData = Convert.FromBase64String(orgData);

            int inputLen = byteData.Length;
            MemoryStream ms = new MemoryStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密
            while (inputLen - offSet > 0)
            {
                if (inputLen - offSet > maxBlockSize)
                {
                    cache = engine.ProcessBlock(byteData, offSet, maxBlockSize);
                }
                else
                {
                    cache = engine.ProcessBlock(byteData, offSet, inputLen - offSet);
                }
                ms.Write(cache, 0, cache.Length);
                i++;
                offSet = i * maxBlockSize;
            }
            byte[] encryptedData = ms.ToArray();

            //var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
            return Encoding.UTF8.GetString(ms.ToArray());
            //Console.WriteLine("密文(base64编码):" + Convert.ToBase64String(testData) + Environment.NewLine);

        }

    }
}

使用

        string formJson = "{\"test\":\"111\"}";
        //私钥长度,常用 1024 或 2048
        int privateKeySize = 2048;
        ////公钥加密
        string strJiamihou = BCSignUtil.EncryptByKey(formJson, v4_FuYouWxPay.Config.PublicKey, true, privateKeySize);
 
        //私钥解密
        string strJiemihou = BCSignUtil.DecryptByKey(strJiamihou, v4_FuYouWxPay.Config.PrivateKey, false, privateKeySize);

上一篇 下一篇

猜你喜欢

热点阅读