zoukankan      html  css  js  c++  java
  • .net中RSA加密解密

    1、产生密钥:

    private static void CreateKey()
            {
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    string publicKey = rsa.ToXmlString(false); // 公钥
                    string privateKey = rsa.ToXmlString(true); // 私钥               
                }
            }

    这里产生的密钥是xml格式的,这也是.net的rsa的密钥格式。但有时候在.net项目中,我们只有java格式的密钥,具体的来说密钥就是一个字符串,这时候需要将其转换为xml格式的。

    //公钥格式的转换
    public static string RsaPublicKeyToXml(string publicKey)
            {
                try
                {
                    if (string.IsNullOrWhiteSpace(publicKey))
                        return "";
                    if (publicKey.Contains("<RSAKeyValue>"))
                        return publicKey;
                    RsaKeyParameters publicKeyParam;
                    //尝试进行java格式的密钥读取
                    try
                    {
                        publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
                    }
                    catch
                    {
                        publicKeyParam = null;
                    }
                    //非java格式密钥进行pem格式的密钥读取
                    if (publicKeyParam == null)
                    {
                        try
                        {
                            var pemKey = publicKey;
                            if (!pemKey.Contains("BEGIN RSA PRIVATE KEY"))
                            {
                                pemKey = @"-----BEGIN RSA PRIVATE KEY-----
                               " + publicKey + @"
                               -----END RSA PRIVATE KEY-----";
                            }
                            var array = Encoding.ASCII.GetBytes(pemKey);
                            var stream = new MemoryStream(array);
                            var reader = new StreamReader(stream);
                            var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(reader);
                            publicKeyParam = (RsaKeyParameters)pemReader.ReadObject();
                        }
                        catch
                        {
                            publicKeyParam = null;
                        }
                    }
                    //如果都解析失败,则返回原串
                    if (publicKeyParam == null)
                        return publicKey;
                    //输出XML格式密钥
                    return string.Format(
                        "<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
                        Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
                        Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned())
                    );
                }
                catch (Exception)
                {
                    return "error";
                }
            }

    //私钥格式转换
    public static string RsaPrivateKeyToXml(string privateKey)
            {
                try
                {
                    if (string.IsNullOrWhiteSpace(privateKey))
                        return "";
                    if (privateKey.Contains("<RSAKeyValue>"))
                        return privateKey;
                    RsaPrivateCrtKeyParameters privateKeyParam;
                    //尝试进行java格式的密钥读取
                    try
                    {
                        privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
                    }
                    catch
                    {
                        privateKeyParam = null;
                    }
                    //非java格式密钥进行pem格式的密钥读取
                    if (privateKeyParam == null)
                    {
                        try
                        {
                            var pemKey = privateKey;
                            if (!pemKey.Contains("BEGIN RSA PRIVATE KEY"))
                            {
                                pemKey = @"-----BEGIN RSA PRIVATE KEY-----
                               " + privateKey + @"
                               -----END RSA PRIVATE KEY-----";
                            }
                            var array = Encoding.ASCII.GetBytes(pemKey);
                            var stream = new MemoryStream(array);
                            var reader = new StreamReader(stream);
                            var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(reader);
                            var keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
                            privateKeyParam = (RsaPrivateCrtKeyParameters)keyPair.Private;
                        }
                        catch
                        {
                            privateKeyParam = null;
                        }
                    }
                    //如果都解析失败,则返回原串
                    if (privateKeyParam == null)
                        return privateKey;
                    //输出XML格式密钥
                    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())
                    );
                }
                catch (Exception)
                {
                    throw PayException.New("RSA私钥密钥格式转换失败");
                }
            }

    2、公钥加密,私钥解密(包括超长字符串的分段加密解密)

    public static string RsaEncrypt(string rawInput, string publicKey)
            {
                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);//有含义的字符串转化为字节流
                    rsaProvider.FromXmlString(publicKey);//载入公钥
                    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, string privateKey)
            {
                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);
                    rsaProvider.FromXmlString(privateKey);
                    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());
                    }
                }
            }

    3、私钥加密,公钥解密(包括超长字符串的分段加密解密)

    /// <summary>
            /// RSA加密 使用私钥加密
            /// </summary>
            /// <param name="byteData"></param>
            /// <param name="key"></param>
            /// <returns></returns>
            private static string RSAEncrypt(string data, string key)
            {
                byte[] byteData = Encoding.UTF8.GetBytes(data);
                var privateRsa = GetRsaCryptoFromXml(key);
                //转换密钥  下面的DotNetUtilities来自Org.BouncyCastle.Security
                var keyPair = DotNetUtilities.GetKeyPair(privateRsa);
    
                var c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
    
                c.Init(true, keyPair.Private);//取私钥(true为加密)
    
               
                int bufferSize = (privateRsa.KeySize / 8) - 11;//单块最大长度
                var buffer = new byte[bufferSize];
                using (MemoryStream inputStream = new MemoryStream(byteData), 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);
                        var encryptedBytes = c.DoFinal(temp);
                        outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
                    }
                    return Convert.ToBase64String( outputStream.ToArray());//转化为字节流方便传输
                }
                
            }
    
            /// <summary>
            /// RSA解密 使用公钥解密
            /// </summary>
            /// <param name="byteData"></param>
            /// <param name="key"></param>
            /// <returns></returns>
            private static string RSADecrypt(string data, string key)
            {
                byte[] byteData= Convert.FromBase64String(data);
                var privateRsa = GetRsaCryptoFromXml(key);
                //转换密钥  
                var keyPair = DotNetUtilities.GetRsaPublicKey(privateRsa);
    
                var c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
    
                c.Init(false, keyPair);//取公钥(false为解密)
    
                using (MemoryStream inputStream = new MemoryStream(byteData), outputStream = new MemoryStream())
                {
                    int restLength = byteData.Length;
                    while (restLength > 0)
                    {
                        int readLength = restLength < 128 ? restLength : 128;
                        restLength = restLength - readLength;
                        byte[] readBytes = new byte[readLength];
                        inputStream.Read(readBytes, 0, readLength);
                        byte[] append = c.DoFinal(readBytes);
                        outputStream.Write(append, 0, append.Length);
                    }
                    //注意,这里不一定就是用utf8的编码方式,这个主要看加密的时候用的什么编码方式
                    return Encoding.UTF8.GetString(outputStream.ToArray());
                }
                
            }
  • 相关阅读:
    2031 HDOJ 进制转换
    计算机视觉实验之直方图均衡化和对数变换
    sublime text3创建文件时生成头部注释
    浏览器调试出错
    css世界-读书笔记
    redis中Bitmaps位图应用场景
    redis中hyperloglog基数统计
    redis中Zset有序集合类型常用命令
    redis中set集合类型常用命令
    redis中hash哈希类型常用命令
  • 原文地址:https://www.cnblogs.com/jin-/p/9243737.html
Copyright © 2011-2022 走看看