rsa加签验签

因为工作需要,要在项目中使用rsa验签,所以就在在网上找了找,网上找的都不能用,就自己改了改。

这个示例中使用了BouncyCastle  nuget包,最新的就行。

所有加签、加密返回结果都是base64的。


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

namespace RSADemo
{
    public class RSAHelper
    {
        #region keys
        const string PUBLICKEY =
@"-----BEGIN PUBLIC KEY-----
公钥
-----END PUBLIC KEY-----
";


        const string PRIVATEKEY =
@"-----BEGIN RSA PRIVATE KEY-----
私钥
-----END RSA PRIVATE KEY-----
";
        #endregion

        
        /// <summary>
        /// 制作签名
        /// </summary>
        /// <param name="encrpyData"></param>
        /// <returns></returns>
        public static string InvokeSign(string encrpyData)
        {
            RSAParameters para = ConvertFromPemPrivateKey(PRIVATEKEY);
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.ImportParameters(para);
            byte[] Data = Encoding.UTF8.GetBytes(encrpyData);
            byte[] signData = rsa.SignData(Data, "SHA1");//使用MD5方式算法制作签名
            return Convert.ToBase64String(signData);

        }


        /// <summary>
        /// 验证签名
        /// </summary>
        /// <param name="data">原始数据</param>
        /// <param name="sign">签名数据</param>
        /// <returns></returns>
        public static bool CheckSign(string data, string sign)
        {
            RSAParameters para = ConvertFromPemPublicKey(PUBLICKEY);//公钥验证
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.ImportParameters(para);
            //MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            //SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            byte[] Data = Encoding.UTF8.GetBytes(data);
            byte[] rgbSignature = Convert.FromBase64String(sign);
            if (rsa.VerifyData(Data, "SHA1", rgbSignature))
            {
                return true;
            }
            return false;
        }

        public static string RsaEncrypt(string rawInput)
        {
            if (string.IsNullOrEmpty(rawInput))
            {
                return string.Empty;
            }

            if (string.IsNullOrWhiteSpace(PUBLICKEY))
            {
                throw new ArgumentException("Invalid Public Key");
            }

            using (var rsaProvider = new RSACryptoServiceProvider())
            {
                var inputBytes = Encoding.UTF8.GetBytes(rawInput);//有含义的字符串转化为字节流
                string pemFileConent = PUBLICKEY.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");
                rsaProvider.FromXmlString(pemFileConent);//载入公钥
                int bufferSize = (rsaProvider.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 = rsaProvider.Encrypt(temp, false);
                        outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
                    }
                    return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输
                }
            }
        }
        public static string RsaDecrypt(string encryptedInput)
        {
            if (string.IsNullOrEmpty(encryptedInput))
            {
                return string.Empty;
            }

            if (string.IsNullOrWhiteSpace(PRIVATEKEY))
            {
                throw new ArgumentException("Invalid Private Key");
            }

            using (var rsaProvider = new RSACryptoServiceProvider())
            {
                var inputBytes = Convert.FromBase64String(encryptedInput);
                string pemFileConent = PRIVATEKEY.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\n", "").Replace("\r", "");
                rsaProvider.FromXmlString(pemFileConent);
                int bufferSize = rsaProvider.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 = rsaProvider.Decrypt(temp, false);
                        outputStream.Write(rawBytes, 0, rawBytes.Length);
                    }
                    return Encoding.UTF8.GetString(outputStream.ToArray());
                }
            }
        }

        public static RSAParameters ConvertFromPemPrivateKey(string serializedPrivate)
        {
            
            serializedPrivate = serializedPrivate.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\n", "").Replace("\r", "");
            RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(serializedPrivate));
            RSACryptoServiceProvider rcsp = new RSACryptoServiceProvider();
            RSAParameters parms = new RSAParameters();
            parms.Modulus = privateKey.Modulus.ToByteArrayUnsigned();
            parms.P = privateKey.P.ToByteArrayUnsigned();
            parms.Q = privateKey.Q.ToByteArrayUnsigned();
            parms.DP = privateKey.DP.ToByteArrayUnsigned();
            parms.DQ = privateKey.DQ.ToByteArrayUnsigned();
            parms.InverseQ = privateKey.QInv.ToByteArrayUnsigned();
            parms.D = privateKey.Exponent.ToByteArrayUnsigned();
            parms.Exponent = privateKey.PublicExponent.ToByteArrayUnsigned();


            return parms;
        }

        /// <summary>
        /// 将pem格式公钥(1024 or 2048)转换为RSAParameters
        /// </summary>
        /// <param name="pemFileConent">pem公钥内容</param>
        /// <returns>转换得到的RSAParamenters</returns>
        public static RSAParameters ConvertFromPemPublicKey(string pemFileConent)
        {
            if (string.IsNullOrEmpty(pemFileConent))
            {
                throw new ArgumentNullException("pemFileConent", "This arg cann't be empty.");
            }
            pemFileConent = pemFileConent.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");
            byte[] keyData = Convert.FromBase64String(pemFileConent);
            bool keySize1024 = (keyData.Length == 162);
            bool keySize2048 = (keyData.Length == 294);
            if (!(keySize1024 || keySize2048))
            {
                throw new ArgumentException("pem file content is incorrect, Only support the key size is 1024 or 2048");
            }
            byte[] pemModulus = (keySize1024 ? new byte[128] : new byte[256]);
            byte[] pemPublicExponent = new byte[3];
            Array.Copy(keyData, (keySize1024 ? 29 : 33), pemModulus, 0, (keySize1024 ? 128 : 256));
            Array.Copy(keyData, (keySize1024 ? 159 : 291), pemPublicExponent, 0, 3);
            RSAParameters para = new RSAParameters();
            para.Modulus = pemModulus;
            para.Exponent = pemPublicExponent;
            return para;
        }
    }
}

发布了16 篇原创文章 · 获赞 0 · 访问量 5689

猜你喜欢

转载自blog.csdn.net/u013608482/article/details/79484283