利用C#的加密库,实现RSA加密算法还是很容易的,因为我只是初步了解这个加密算法,据说是目前非对称加密中比较优秀的加密算法了,如银行什么的都在在RSA1024 RSA2048 RSA4096之类,后面的数字,我想,越大,越复杂,破解也越困难吧。。
RSA加密也很复杂,把几位数加密后,变成了很大的字符串(一般为十六进制字符串),当然也可以使用BASE64处理一下,因为加密后的数值,有可能不是可以显示的字符。
主要的加密算法如下:
(1)加密类:网上找来的,能用。。
- 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);
- }
- }
- }
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);
}
}
}
实现起来很容易。代码如下:
- 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();
- }
- }
- }
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加密与解密的基础,以后有时间,多了解!
工程测试源码下载:点击打开链接