在我们现实当中经常会存在需要对某些数据进行加密保护 然后进行解密的操作,比方,我们需要对某些XML配置信息里面的某些数据进行加密,以防止任何人打开该XML配置信息都能正常的看到该配置信息里面的内容,从而被人家篡改程序,甚至致使系统崩溃.下面我就谈下现在比较常用的RSA算法以及如何在Visual C#中如何实现.
 
1.首先介绍下什么是RSA算法,让大家对RSA算法有个简要的理解.
   RSA算法非常简单,概述如下:
  找两素数p和q
   取n=p*q  如:n=3*7=21
   取t=(p-1)*(q-1) 如:t = 2*6 = 12
   取任何一个数e,要求满足e
  取d*e%t==1  如:d=7,e=7,则7*7/12刚好等于1满足要求
  这样最终得到三个数: n d e,即 n=21,d=7,e=7
  设消息为数M
  设c=(M**d)%n就得到了加密后的消息c
  设m=(c**e)%n则 m == M,从而完成对c的解密。
  注:**表示次方,上面两式中的d和e可以互换。
 
  在对称加密中:
  n d两个数构成公钥,可以告诉别人;
  n e两个数构成私钥,e自己保留,不让任何人知道。
  给别人发送的信息使用e加密,只要别人能用d解开就证明信息是由你发送的,构成了签名机制。
  别人给你发送信息时使用d加密,这样只有拥有e的你能够对其解密。
  rsa的安全性在于对于一个大数n,没有有效的方法能够将其分解从而在已知n d的情况无法获得e;同样在已知n e的情况下无法求得d。
 
2.上面就是对RSA算法的一个简要概括,该描述在很多书本上都有介绍,这里也就不做过多解释了,下面我们看下在.net 里面如何实现该算法.
   在.net 里面,有一个叫RSACryptoServiceProvider的类,在MSDN中,我们可以了解到该类使用加密服务提供程序 (CSP) 提供的rsa算法的实现,执行不对称加密和解密,从继承关系上我们了解到该类继承自RSA类.通过该类,我们可以导出加密解密所需要的XML信息,并且能够根据我们提供的XML信息进行加密解密计算,下面是对该类的一些具体操作,主要包括如何导出密钥,如何用形成的密钥进行加密和解密,完成我们一般的操作.
   public class Cyh_RSA
    {
        public Cyh_RSA()
        {
           
        }
 
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="p_inputString">需要加密的字符串信息</param>
        /// <param name="p_strKeyPath">加密用的密钥所在的路径(*.cyh_publickey)</param>
        /// <returns>加密以后的字符串信息</returns>
        public string Encrypt(string p_inputString, string p_strKeyPath)
        {
            string fileString = null;
            string outString = null;
            if (File.Exists(p_strKeyPath))
            {
                StreamReader streamReader = new StreamReader(p_strKeyPath, true);
                fileString = streamReader.ReadToEnd();
                streamReader.Close();
 
            }
 
            if (fileString != null)
            {
                string bitStrengthString = fileString.Substring(0, fileString.IndexOf("</BitStrength>") + 14);
                fileString = fileString.Replace(bitStrengthString, "");
                int bitStrength = Convert.ToInt32(bitStrengthString.Replace("<BitStrength>", "").Replace("</BitStrength>", ""));
                try
                {
                    outString = EncryptString(p_inputString, bitStrength, fileString);
                }
                catch (Exception Ex)
                {
                    MessageBox.Show("出错: \n" + Ex.Message);
                }
 
            }
 
            return outString;
        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="p_inputString">需要解密的字符串信息</param>
        /// <param name="p_strKeyPath">解密用的密钥所在的路径(*.cyh_primarykey)</param>
        /// <returns>解密以后的字符串信息</returns>
        public string Decrypt(string p_inputString, string p_strKeyPath)
        {
            string fileString = null;
            string outString = null;
            if (File.Exists(p_strKeyPath))
            {
                StreamReader streamReader = new StreamReader(p_strKeyPath, true);
                fileString = streamReader.ReadToEnd();
                streamReader.Close();
 
            }
 
            if (fileString != null)
            {
                string bitStrengthString = fileString.Substring(0, fileString.IndexOf("</BitStrength>") + 14);
                fileString = fileString.Replace(bitStrengthString, "");
                int bitStrength = Convert.ToInt32(bitStrengthString.Replace("<BitStrength>", "").Replace("</BitStrength>", ""));
                try
                {
                    outString = DecryptString(p_inputString, bitStrength, fileString);
                }
                catch (Exception Ex)
                {
                    MessageBox.Show("出错: \n" + Ex.Message);
                }
 
            }
 
            return outString;
 
        }
 
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="p_inputString">需要加密的字符串</param>
        /// <param name="p_dwKeySize">密钥的大小</param>
        /// <param name="p_xmlString">包含密钥的XML文本信息</param>
        /// <returns>加密后的文本信息</returns>
        private string EncryptString(string p_inputString, int p_dwKeySize, string p_xmlString)
        {
            RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider(p_dwKeySize);
            rsaCryptoServiceProvider.FromXmlString(p_xmlString);
            int keySize = p_dwKeySize / 8;
            byte[] bytes = Encoding.UTF32.GetBytes(p_inputString);
            int maxLength = keySize - 42;
            int dataLength = bytes.Length;
            int iterations = dataLength / maxLength;
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i <= iterations; i++)
            {
                byte[] tempBytes = new byte[(dataLength - maxLength * i > maxLength) ? maxLength : dataLength - maxLength * i];
                Buffer.BlockCopy(bytes, maxLength * i, tempBytes, 0, tempBytes.Length);
                byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt(tempBytes, true);
                Array.Reverse(encryptedBytes);
                stringBuilder.Append(Convert.ToBase64String(encryptedBytes));
            }
            return stringBuilder.ToString();
        }
 
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="p_inputString">需要解密的字符串信息</param>
        /// <param name="p_dwKeySize">密钥的大小</param>
        /// <param name="p_xmlString">包含密钥的文本信息</param>
        /// <returns>解密后的文本信息</returns>
        private string DecryptString(string inputString, int dwKeySize, string xmlString)
        {
            RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider(dwKeySize);
            rsaCryptoServiceProvider.FromXmlString(xmlString);
            int base64BlockSize = ((dwKeySize / 8) % 3 != 0) ? (((dwKeySize / 8) / 3) * 4) + 4 : ((dwKeySize / 8) / 3) * 4;
            int iterations = inputString.Length / base64BlockSize;
            ArrayList arrayList = new ArrayList();
            for (int i = 0; i < iterations; i++)
            {
                byte[] encryptedBytes = Convert.FromBase64String(inputString.Substring(base64BlockSize * i, base64BlockSize));
                Array.Reverse(encryptedBytes);
                arrayList.AddRange(rsaCryptoServiceProvider.Decrypt(encryptedBytes, true));
            }
            return Encoding.UTF32.GetString(arrayList.ToArray(Type.GetType("System.Byte")) as byte[]);
        }
 
        /// <summary>
        /// 形成并保存公开密钥和私有密钥
        /// </summary>
        /// <param name="p_currentBitStrength">密钥大小</param>
        public void SaveKey(int p_currentBitStrength)
        {
            RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider(p_currentBitStrength);
            string publicAndPrivateKeys = "<BitStrength>" + p_currentBitStrength.ToString() + "</BitStrength>" + RSAProvider.ToXmlString(true);
            string justPublicKey = "<BitStrength>" + p_currentBitStrength.ToString() + "</BitStrength>" + RSAProvider.ToXmlString(false);
            if (saveFile("Save Public/Private Keys As", "Public/Private Keys Document( *.cyh_primarykey )|*.cyh_primarykey", publicAndPrivateKeys))
            { while (!saveFile("Save Public Key As", "Public Key Document( *.cyh_publickey )|*.cyh_publickey", justPublicKey)) { ; } }
        }
 
        /// <summary>
        /// 保存信息
        /// </summary>
        /// <param name="p_title">标题</param>
        /// <param name="p_filterString">过滤条件</param>
        /// <param name="p_outputString">输出内容</param>
        /// <returns>是否成功</returns>
        private bool saveFile(string p_title, string p_filterString, string p_outputString)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = p_title;
            saveFileDialog.Filter = p_filterString;
            saveFileDialog.FileName = "";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    StreamWriter streamWriter = new StreamWriter(saveFileDialog.FileName, false);
                    if (p_outputString != null)
                    { streamWriter.Write(p_outputString); }
                    streamWriter.Close();
                    return true;
                }
                catch (Exception Ex)
                {
                    Console.WriteLine(Ex.Message);
                    return false;
                }
            }
            return false;
        }
    }
这样,您在任何地方都可以使用该类对数据进行加密和解密,并且操作相当方便,如:
生成密钥:
 Cyh_RSA rsa = new Cyh_RSA();
 rsa.SaveKey(1024);
加密:
Cyh_RSA rsa = new Cyh_RSA();
rsa.Encrypt("需要加密的内容", "包含密钥的路径");
解密:
Cyh_RSA rsa = new Cyh_RSA();
rsa.Decrypt("需要解密的内容", "包含密钥的路径");

[转]应用RSACryptoServiceProvider类轻松实现RSA算法的更多相关文章

  1. C# 基于大整数类的RSA算法实现(公钥加密私钥解密,私钥加密公钥解密)

    但是C#自带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实现是基于网上提供的一个大整 ...

  2. Asp.Net 常用工具类之加密——非对称加密RSA算法

    踏入程序员这个行业也有几年了,几年中有收获(技术加强),有付出(时间和亚健康状态).当然喏,并不后悔,代码路还长!!! On The Way,永不止步!!! 开发过程中也积累了一些自己的经验.代码块和 ...

  3. RSA算法java实现(BigInteger类的各种应用)

    一.RSA算法 1.密钥生成 随机生成两个大素数p.q 计算n=p*q 计算n的欧拉函数f=(p-1)*(q-1) 选取1<e<f,使e与f互素 计算d,ed=1modf 公钥为(e,n) ...

  4. C#RSA算法实现+如何将公钥为XML格式转为PEM格式,给object-C使用

    .net中,处于安全的考虑,RSACryptoServiceProvider类,解密时只有同时拥有公钥和私钥才可以.原因是公钥是公开的,会被多人持有.这样的数据传输是不安全的.C#RSA私钥加密,公钥 ...

  5. 基于私钥加密公钥解密的RSA算法C#实现

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...

  6. 非对称加密RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。使用最广泛的是RSA算法

          非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey).公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密:如果用私 ...

  7. .NET Core 使用RSA算法 加密/解密/签名/验证签名

    前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲. RSA在.NET C ...

  8. 实现 RSA 算法之改进和优化(第三章)(老物)

    第三章 如何改进和优化RSA算法 这章呢,我想谈谈在实际应用出现的问题和理解. 由于近期要开始各种忙了,所以写完这章后我短时间内也不打算出什么资料了=- =(反正平时就没有出资料的习惯.) 在讲第一章 ...

  9. 实现 RSA 算法之基础公式证明(第一章)(老物)

    写这篇日志是拖了很久的事情,以前说要写些算法相关的文章给想学信息安全学(简称信安),密码学的同学提供些入门资料,毕竟这种知识教师上课也不会细讲太多(纯理论偏重),更不用说理解和应用了,说到RSA公钥( ...

随机推荐

  1. 纯CSS3实现蜡烛(冒烟)效果

    1. 闲来无事时在网上看一些前辈的博客文章,自己尝试了一下.学习到最重要的一点就是box-shadow的叠加使用,受益非线.先上一下效果图: 其中有以下重要的几点: 1. 蜡烛底座的border-ra ...

  2. 【BZOJ 1430】 1430: 小猴打架 (Prufer数列)

    1430: 小猴打架 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 625  Solved: 452 Description 一开始森林里面有N只互不相 ...

  3. 【2017 4 24 - B】 组合数

    [题目描述] 输入格式: 一行一个正整数n 输出格式: 一行一个数f(n)对1000000007取余的值 [分析] 就是乱搞?? 就是问根到叶子有多少条路径嘛. 然后路径可以π.1.1.π...这样表 ...

  4. BZOJ.2660.[BJOI2012]最多的方案(DP)

    题目链接 首先我们知道: 也很好理解.如果相邻两项出现在斐波那契表示法中,那它们显然可以合并. 所以我们能得到\(n\)的斐波那契表示,记\(pos[i]\)为\(n\)的斐波那契表示法中,第\(i\ ...

  5. BZOJ3779 : 重组病毒

    一个点的感染时间为它到根路径上虚边数+1. 用Link-Cut Tree模拟虚实边切换,每次切换时等价于在一段或两段DFS序区间更新,线段树维护即可. 时间复杂度$O(n\log^2n)$. #inc ...

  6. Linux学习笔记07—mysql的配置

    一.mysql简介 说到数据库,我们大多想到的是关系型数据库,比如mysql.oracle.sqlserver等等,这些数据库软件在windows上安装都非常的方便,在Linux上如果要安装数据库,咱 ...

  7. Jmeter自定义编写Java代码调用socket通信

    一.前言 最近需要测试一款手机游戏的性能,找不到啥录制脚本的工具,然后,另外想办法.性能测试实际上就是对服务器的承载能力的测试,和各种类型的手机客户端没有啥多大关系,手机再好,服务器负载不了,也不能够 ...

  8. 使用 IntraWeb (18) - 基本控件之 TIWImage、TIWImageFile、TIWImageList

    TIWImage //用于显示资源中的图片, 设计时通过 Picture 载入图片到资源 TIWImageFile //用于显示给定路径或地址的图片 TIWImageList //它继承于 TImag ...

  9. CentOS 7设置ulimit不生效的问题解决

    sed -i 's/#UseLogin no/UseLogin yes/g' /etc/ssh/sshd_configservice sshd restart 重新登录后查看效果: ulimit -n ...

  10. 【原创】Nginx+PHP-FPM优化技巧总结(转)

    php-fpm的安装很简单,参见PHP(PHP-FPM)手动编译安装.下面主要讨论下如何提高Nginx+Php-fpm的性能.   1.Unix域Socket通信   之前简单介绍过Unix Doma ...