C#实现字符串RSA加密与解密算法

    利用C#的加密库,实现RSA加密算法还是很容易的,因为我只是初步了解这个加密算法,据说是目前非对称加密中比较优秀的加密算法了,如银行什么的都在在RSA1024 RSA2048 RSA4096之类,后面的数字,我想,越大,越复杂,破解也越困难吧。。

        RSA加密也很复杂,把几位数加密后,变成了很大的字符串(一般为十六进制字符串),当然也可以使用BASE64处理一下,因为加密后的数值,有可能不是可以显示的字符。


主要的加密算法如下:

(1)加密类:网上找来的,能用。。

[csharp] view plain copy
print ?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Security.Cryptography;  
  5. using System.IO;  
  6. using System.Xml;  
  7.   
  8. namespace RSA_V1  
  9. {  
  10.     class RSAUtil  
  11.     {  
  12.         public void CreateRSAKey()  
  13.         {  
  14.   
  15.             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();  
  16.             RSAParameters keys = rsa.ExportParameters(true);  
  17.             String pkxml = "<root>\n<Modulus>" + ToHexString(keys.Modulus) + "</Modulus>";  
  18.             pkxml += "\n<Exponent>" + ToHexString(keys.Exponent) + "</Exponent>\n</root>";  
  19.             String psxml = "<root>\n<Modulus>" + ToHexString(keys.Modulus) + "</Modulus>";  
  20.             psxml += "\n<Exponent>" + ToHexString(keys.Exponent) + "</Exponent>";  
  21.             psxml += "\n<D>" + ToHexString(keys.D) + "</D>";  
  22.             psxml += "\n<DP>" + ToHexString(keys.DP) + "</DP>";  
  23.             psxml += "\n<P>" + ToHexString(keys.P) + "</P>";  
  24.             psxml += "\n<Q>" + ToHexString(keys.Q) + "</Q>";  
  25.             psxml += "\n<DQ>" + ToHexString(keys.DQ) + "</DQ>";  
  26.             psxml += "\n<InverseQ>" + ToHexString(keys.InverseQ) + "</InverseQ>\n</root>";  
  27.   
  28.             SaveToFile("publickey.xml", pkxml);  
  29.             SaveToFile("privatekey.xml", psxml);  
  30.   
  31.         }  
  32.         public RSACryptoServiceProvider CreateRSADEEncryptProvider(String privateKeyFile)  
  33.         {  
  34.             RSAParameters parameters1;  
  35.             parameters1 = new RSAParameters();  
  36.             StreamReader reader1 = new StreamReader(privateKeyFile);  
  37.             XmlDocument document1 = new XmlDocument();  
  38.             document1.LoadXml(reader1.ReadToEnd());  
  39.             XmlElement element1 = (XmlElement)document1.SelectSingleNode("root");  
  40.             parameters1.Modulus = ReadChild(element1, "Modulus");  
  41.             parameters1.Exponent = ReadChild(element1, "Exponent");  
  42.             parameters1.D = ReadChild(element1, "D");  
  43.             parameters1.DP = ReadChild(element1, "DP");  
  44.             parameters1.DQ = ReadChild(element1, "DQ");  
  45.             parameters1.P = ReadChild(element1, "P");  
  46.             parameters1.Q = ReadChild(element1, "Q");  
  47.             parameters1.InverseQ = ReadChild(element1, "InverseQ");  
  48.             CspParameters parameters2 = new CspParameters();  
  49.             parameters2.Flags = CspProviderFlags.UseMachineKeyStore;  
  50.             RSACryptoServiceProvider provider1 = new RSACryptoServiceProvider(parameters2);  
  51.             provider1.ImportParameters(parameters1);  
  52.             reader1.Close();  
  53.             return provider1;  
  54.         }  
  55.         public RSACryptoServiceProvider CreateRSAEncryptProvider(String publicKeyFile)  
  56.         {  
  57.             RSAParameters parameters1;  
  58.             parameters1 = new RSAParameters();  
  59.             StreamReader reader1 = new StreamReader(publicKeyFile);  
  60.             XmlDocument document1 = new XmlDocument();  
  61.             document1.LoadXml(reader1.ReadToEnd());  
  62.             XmlElement element1 = (XmlElement)document1.SelectSingleNode("root");  
  63.             parameters1.Modulus = ReadChild(element1, "Modulus");  
  64.             parameters1.Exponent = ReadChild(element1, "Exponent");  
  65.             CspParameters parameters2 = new CspParameters();  
  66.             parameters2.Flags = CspProviderFlags.UseMachineKeyStore;  
  67.             RSACryptoServiceProvider provider1 = new RSACryptoServiceProvider(parameters2);  
  68.             provider1.ImportParameters(parameters1);  
  69.             reader1.Close();  
  70.             return provider1;  
  71.         }  
  72.   
  73.         public byte[] ReadChild(XmlElement parent, string name)  
  74.         {  
  75.             XmlElement element1 = (XmlElement)parent.SelectSingleNode(name);  
  76.             return hexToBytes(element1.InnerText);  
  77.         }  
  78.   
  79.         public string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "  
  80.         {  
  81.             string hexString = string.Empty;  
  82.             if (bytes != null)  
  83.             {  
  84.                 StringBuilder strB = new StringBuilder();  
  85.   
  86.                 for (int i = 0; i < bytes.Length; i++)  
  87.                 {  
  88.                     strB.Append(bytes[i].ToString("X2"));  
  89.                 }  
  90.                 hexString = strB.ToString();  
  91.             }  
  92.             return hexString;  
  93.         }  
  94.         public byte[] hexToBytes(String src)  
  95.         {  
  96.             int l = src.Length / 2;  
  97.             String str;  
  98.             byte[] ret = new byte[l];  
  99.   
  100.             for (int i = 0; i < l; i++)  
  101.             {  
  102.                 str = src.Substring(i * 2, 2);  
  103.                 ret[i] = Convert.ToByte(str, 16);  
  104.             }  
  105.             return ret;  
  106.         }  
  107.   
  108.         public void SaveToFile(String filename, String data)  
  109.         {  
  110.             System.IO.StreamWriter sw = System.IO.File.CreateText(filename);  
  111.             sw.WriteLine(data);  
  112.             sw.Close();  
  113.         }  
  114.   
  115.         public string EnCrypt(string str)  
  116.         {  
  117.             RSACryptoServiceProvider rsaencrype = CreateRSAEncryptProvider("publickey.xml");  
  118.             String text = str;  
  119.             byte[] data = new UnicodeEncoding().GetBytes(text);  
  120.             byte[] endata = rsaencrype.Encrypt(data, true);  
  121.             return ToHexString(endata);  
  122.         }  
  123.   
  124.         public string DoEncrypt(string hexstr)  
  125.         {  
  126.             RSACryptoServiceProvider rsadeencrypt = CreateRSADEEncryptProvider("privatekey.xml");  
  127.   
  128.             byte[] miwen = hexToBytes(hexstr);  
  129.   
  130.             byte[] dedata = rsadeencrypt.Decrypt(miwen, true);  
  131.   
  132.             return System.Text.UnicodeEncoding.Unicode.GetString(dedata);  
  133.         }  
  134.     }  
  135. }  
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Xml;

namespace RSA_V1
{
    class RSAUtil
    {
        public void CreateRSAKey()
        {

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            RSAParameters keys = rsa.ExportParameters(true);
            String pkxml = "<root>\n<Modulus>" + ToHexString(keys.Modulus) + "</Modulus>";
            pkxml += "\n<Exponent>" + ToHexString(keys.Exponent) + "</Exponent>\n</root>";
            String psxml = "<root>\n<Modulus>" + ToHexString(keys.Modulus) + "</Modulus>";
            psxml += "\n<Exponent>" + ToHexString(keys.Exponent) + "</Exponent>";
            psxml += "\n<D>" + ToHexString(keys.D) + "</D>";
            psxml += "\n<DP>" + ToHexString(keys.DP) + "</DP>";
            psxml += "\n<P>" + ToHexString(keys.P) + "</P>";
            psxml += "\n<Q>" + ToHexString(keys.Q) + "</Q>";
            psxml += "\n<DQ>" + ToHexString(keys.DQ) + "</DQ>";
            psxml += "\n<InverseQ>" + ToHexString(keys.InverseQ) + "</InverseQ>\n</root>";

            SaveToFile("publickey.xml", pkxml);
            SaveToFile("privatekey.xml", psxml);

        }
        public RSACryptoServiceProvider CreateRSADEEncryptProvider(String privateKeyFile)
        {
            RSAParameters parameters1;
            parameters1 = new RSAParameters();
            StreamReader reader1 = new StreamReader(privateKeyFile);
            XmlDocument document1 = new XmlDocument();
            document1.LoadXml(reader1.ReadToEnd());
            XmlElement element1 = (XmlElement)document1.SelectSingleNode("root");
            parameters1.Modulus = ReadChild(element1, "Modulus");
            parameters1.Exponent = ReadChild(element1, "Exponent");
            parameters1.D = ReadChild(element1, "D");
            parameters1.DP = ReadChild(element1, "DP");
            parameters1.DQ = ReadChild(element1, "DQ");
            parameters1.P = ReadChild(element1, "P");
            parameters1.Q = ReadChild(element1, "Q");
            parameters1.InverseQ = ReadChild(element1, "InverseQ");
            CspParameters parameters2 = new CspParameters();
            parameters2.Flags = CspProviderFlags.UseMachineKeyStore;
            RSACryptoServiceProvider provider1 = new RSACryptoServiceProvider(parameters2);
            provider1.ImportParameters(parameters1);
            reader1.Close();
            return provider1;
        }
        public RSACryptoServiceProvider CreateRSAEncryptProvider(String publicKeyFile)
        {
            RSAParameters parameters1;
            parameters1 = new RSAParameters();
            StreamReader reader1 = new StreamReader(publicKeyFile);
            XmlDocument document1 = new XmlDocument();
            document1.LoadXml(reader1.ReadToEnd());
            XmlElement element1 = (XmlElement)document1.SelectSingleNode("root");
            parameters1.Modulus = ReadChild(element1, "Modulus");
            parameters1.Exponent = ReadChild(element1, "Exponent");
            CspParameters parameters2 = new CspParameters();
            parameters2.Flags = CspProviderFlags.UseMachineKeyStore;
            RSACryptoServiceProvider provider1 = new RSACryptoServiceProvider(parameters2);
            provider1.ImportParameters(parameters1);
            reader1.Close();
            return provider1;
        }

        public byte[] ReadChild(XmlElement parent, string name)
        {
            XmlElement element1 = (XmlElement)parent.SelectSingleNode(name);
            return hexToBytes(element1.InnerText);
        }

        public string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
        {
            string hexString = string.Empty;
            if (bytes != null)
            {
                StringBuilder strB = new StringBuilder();

                for (int i = 0; i < bytes.Length; i++)
                {
                    strB.Append(bytes[i].ToString("X2"));
                }
                hexString = strB.ToString();
            }
            return hexString;
        }
        public byte[] hexToBytes(String src)
        {
            int l = src.Length / 2;
            String str;
            byte[] ret = new byte[l];

            for (int i = 0; i < l; i++)
            {
                str = src.Substring(i * 2, 2);
                ret[i] = Convert.ToByte(str, 16);
            }
            return ret;
        }

        public void SaveToFile(String filename, String data)
        {
            System.IO.StreamWriter sw = System.IO.File.CreateText(filename);
            sw.WriteLine(data);
            sw.Close();
        }

        public string EnCrypt(string str)
        {
            RSACryptoServiceProvider rsaencrype = CreateRSAEncryptProvider("publickey.xml");
            String text = str;
            byte[] data = new UnicodeEncoding().GetBytes(text);
            byte[] endata = rsaencrype.Encrypt(data, true);
            return ToHexString(endata);
        }

        public string DoEncrypt(string hexstr)
        {
            RSACryptoServiceProvider rsadeencrypt = CreateRSADEEncryptProvider("privatekey.xml");

            byte[] miwen = hexToBytes(hexstr);

            byte[] dedata = rsadeencrypt.Decrypt(miwen, true);

            return System.Text.UnicodeEncoding.Unicode.GetString(dedata);
        }
    }
}


(2)WinForm实现,我不太喜欢控制台的程序,其实有界面的软件才更美观。

实现起来很容易。代码如下:


[csharp] view plain copy
print ?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Threading.Tasks;  
  9. using System.Windows.Forms;  
  10. using System.Security.Cryptography;  
  11. using System.Xml;  
  12. using System.IO;  
  13.   
  14.   
  15.   
  16. namespace RSA_V1  
  17. {  
  18.     public partial class RSA_Frm : Form  
  19.     {  
  20.         RSAUtil rsa = new RSAUtil();  
  21.   
  22.         public RSA_Frm()  
  23.         {  
  24.             InitializeComponent();  
  25.         }  
  26.   
  27.         private void btn_Encrypt_Click(object sender, EventArgs e)  
  28.         {  
  29.             txt_DST.Text = rsa.EnCrypt(txt_SRC.Text);  
  30.         }  
  31.   
  32.         private void btn_Decrypt_Click(object sender, EventArgs e)  
  33.         {  
  34.             txt_SRC.Text = rsa.DoEncrypt(txt_DST.Text);  
  35.         }  
  36.   
  37.         private void RSA_Frm_Load(object sender, EventArgs e)  
  38.         {  
  39.             New_Key();            
  40.         }  
  41.   
  42.         private void btn_NewKey_Click(object sender, EventArgs e)  
  43.         {  
  44.             New_Key();  
  45.         }  
  46.   
  47.         private void New_Key()  
  48.         {  
  49.            rsa.CreateRSAKey();  
  50.             StreamReader reader1 = new StreamReader("privatekey.xml");  
  51.             XmlDocument document1 = new XmlDocument();  
  52.             document1.LoadXml(reader1.ReadToEnd());  
  53.             XmlElement element1 = (XmlElement)document1.SelectSingleNode("root");  
  54.             //parameters1.Modulus = ReadChild(element1, "Modulus");  
  55.             txt_RSA_E.Text = rsa.ToHexString(rsa.ReadChild(element1, "Exponent"));  
  56.             txt_RSA_D.Text = rsa.ToHexString(rsa.ReadChild(element1, "D"));  
  57.             txt_RSA_Q.Text = rsa.ToHexString(rsa.ReadChild(element1, "Q"));  
  58.             txt_RSA_P.Text = rsa.ToHexString(rsa.ReadChild(element1, "P"));  
  59.             //parameters1.DP = ReadChild(element1, "DP");  
  60.             //parameters1.DQ = ReadChild(element1, "DQ");  
  61.             //parameters1.P = ReadChild(element1, "P");  
  62.             //parameters1.Q = ReadChild(element1, "Q");  
  63.             //parameters1.InverseQ = ReadChild(element1, "InverseQ");  
  64.             reader1.Close();  
  65.         }  
  66.     }  
  67. }  
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.Xml;
using System.IO;



namespace RSA_V1
{
    public partial class RSA_Frm : Form
    {
        RSAUtil rsa = new RSAUtil();

        public RSA_Frm()
        {
            InitializeComponent();
        }

        private void btn_Encrypt_Click(object sender, EventArgs e)
        {
            txt_DST.Text = rsa.EnCrypt(txt_SRC.Text);
        }

        private void btn_Decrypt_Click(object sender, EventArgs e)
        {
            txt_SRC.Text = rsa.DoEncrypt(txt_DST.Text);
        }

        private void RSA_Frm_Load(object sender, EventArgs e)
        {
            New_Key();          
        }

        private void btn_NewKey_Click(object sender, EventArgs e)
        {
            New_Key();
        }

        private void New_Key()
        {
           rsa.CreateRSAKey();
            StreamReader reader1 = new StreamReader("privatekey.xml");
            XmlDocument document1 = new XmlDocument();
            document1.LoadXml(reader1.ReadToEnd());
            XmlElement element1 = (XmlElement)document1.SelectSingleNode("root");
            //parameters1.Modulus = ReadChild(element1, "Modulus");
            txt_RSA_E.Text = rsa.ToHexString(rsa.ReadChild(element1, "Exponent"));
            txt_RSA_D.Text = rsa.ToHexString(rsa.ReadChild(element1, "D"));
            txt_RSA_Q.Text = rsa.ToHexString(rsa.ReadChild(element1, "Q"));
            txt_RSA_P.Text = rsa.ToHexString(rsa.ReadChild(element1, "P"));
            //parameters1.DP = ReadChild(element1, "DP");
            //parameters1.DQ = ReadChild(element1, "DQ");
            //parameters1.P = ReadChild(element1, "P");
            //parameters1.Q = ReadChild(element1, "Q");
            //parameters1.InverseQ = ReadChild(element1, "InverseQ");
            reader1.Close();
        }
    }
}


运行的效果如下:



            目前只是使用C#自带的功能,如生成密钥对等,还不支持自己定义的密钥对,打算有时间继续完善一下。RSA是大数模运算架起来的,这个倒底安不安全不敢说。

总之,同一个字符串,加密后有N多种的密文,每一个密文,都可以通过私钥得到正确的解密。一把锁,有几把钥匙,这本身不太安全吧。


         我觉得如果研究一下同一字符串 公钥相同的情况下,得到不同的密文,这些密文有什么关系呢?有时间可以先用小的素数进行测试一下。大整数,大素数的模幂运算,是RSA加密与解密的基础,以后有时间,多了解!


工程测试源码下载:点击打开链接

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值