.net中RSA加密解密

摘要:
但有时在。net项目,我们只有java格式的密钥。具体来说,键是一个字符串。此时,它需要转换为xml格式//公钥格式转换publicstaticringRsaPublicKeyToXml{try{ifreturn“”;ifreturnpublicKey;RsaKeyParameterspublicKeyParam;//尝试以java格式读取密钥,请尝试{publicKeyParam=PublicKeyFactory.CreateKey;}catch{publicKeyParam=null;}//如果{try{varpemKey=publicKey;if(!

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());
            }
            
        }

免责声明:文章转载自《.net中RSA加密解密》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于几种获取iOS设备UDID典型方式的技术探讨vi 整行 多行 复制与粘贴下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

遍历树,找出所有叶子路径

一、示例: 树的结构: 示例中自己构建了图片中的这棵树: 树节点模型: public class TreeNode { String value; List<TreeNode> children; public TreeNode() { children = new ArrayList<>...

JavaScriptDate(日期)

如何使用Date()方法获取当日的日期。 getFullYear(); 使用getFullYear()获取年份。 getTime(); getTime()返回1970年1月1日至今的毫秒数。 setFullYear(); 使用setFullYear()设置具体日期。 toUTCString(); 使用toUTCString()将当前日期(根据UTC)转换为...

Delphi管理多线程之线程局部存储:threadvar

尽管多线程能够解决许多问题,但是同时它又给我们带来了很多的问题。其中主要的问题就是:对全局变量或句柄这样的全局资源如何访问?另外,当必须确保一个线程中的某些事件要在另一个线程中的其他时间之前(或之后)发生时,该怎么办?这里将讲解通过使用由 Delphi提供的线程局部存储和 A P I为线程提供同步的方法。 这里先讲线程局部存储,下一篇再讲线程同步 线程局部...

CodeSmith使用方法

CodeSmith(1):使用和语法简介 http://www.cnblogs.com/duanzt/archive/2005/12/31/308665.html 下载: 官方网站:http://www.codesmithtools.com/ 5.0破解文件下载:http://kewlshare.com/dl/0538fcf454d3/CodeSmit...

spring boot 中用@value给static变量赋值

需求:改写一个JedisUtils,工具类,所以最好用静态方法和变量。 @value("${redis.host}") private static String redisHost; 运行后发现注入失败。解决办法:看了网上大家的说法,有用中间变量的,有用set方法赋值的。试了一下都是可以成功赋值的, 以下引用别人的代码: 给参数注入,执行set方法(这里...

autossh使用(本机记住ssh密码)

autossh版本说明 目前发现同样叫autossh的,有好几个项目 yum,brew中的自动重启ssh会话和隧道 FeeiCN的autossh islenbo的autossh 后面两个的主要是用于记录密码,远程连接 Feeicn版安装使用 安装依赖: Linux yum install expect apt-get install expect...