Rocho.J

人脑是不可靠的, 随时记录感悟并且经常重复!

 

[转]RSA非对称加密算法实现相关的帖子

 基于私钥加密公钥解密的RSA算法C#实现     ---    转自:http://blog.163.com/da7_1@126/blog/static/10407267820111137637272/

RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。
RSA的安全性依赖于大数分解。公钥和私钥都是两个大素数( 大于 100个十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积。
密钥对的产生。选择两个大素数,p 和q 。计算:
n = p * q
然后随机选择加密密钥e(PS:最常用的e值有3,17和65537,微软就是使用的65537,采用3个中的任何一个都不存在安全问题),要求 e 和 ( p - 1 ) * ( q - 1 ) 互质。最后,利用Euclid 算法计算解密密钥d, 满足
e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) )
其中n和d也要互质。数e和n是公钥,d是私钥。两个素数p和q不再需要,应该丢弃,不要让任何人知道。
加密信息 m(二进制表示)时,首先把m分成等长数据块 m1 ,m2,..., mi ,块长s,其中 2^s <= n, s 尽可能的大。对应的密文是:
ci = mi^e ( mod n ) ( a )
解密时作如下计算:
mi = ci^d ( mod n ) ( b )

.NET提供常用的加密算法类,支持RSA的类是RSACryptoServiceProvider(命名空间:System.Security.Cryptography),但只支持公钥加密,私钥解密。RSACryptoServiceProvider类包括:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D等8个属性,其中Modulus和Exponent就是公钥,Modulus和D就是私钥,RSACryptoServiceProvider类提供导出公钥的方法,也提供导出私钥的方法,但导出的私钥包含上面8个属性,显然要用RSACryptoServiceProvider实现私钥加密公钥是不可行的。

从RSA的原理来看,公钥加密私钥解密和私钥加密公钥解密应该是等价的,在某些情况下,比如共享软件加密,我们需要用私钥加密注册码或注册文件,发给用户,用户用公钥解密注册码或注册文件进行合法性验证。

本人利用网上找的一个C#版的大整数类BigInteger(本人认为这是偶发现的效率最高的一个C#版大整数类)来实现私钥加密公钥加密(事实上也完全支持公租加密私钥解密),但没有使用类BigInteger的大素数生成函数,而是直接使用类RSACryptoServiceProvider来生成大素数。
其中加密函数和解密函数的实现如下:

       /* 
功能:用指定的私钥(n,d)加密指定字符串source 
*/ 
private string EncryptString(string source, BigInteger d, BigInteger n) 
{ 
int len = source.Length; 
int len1 = 0; 
int blockLen = 0; 
if ((len % 128) == 0) 
len1 = len / 128; 
else 
len1 = len / 128 + 1; 
string block = ""; 
string temp = ""; 
for (int i = 0; i < len1; i++) 
{ 
if (len >= 128) 
blockLen = 128; 
else 
blockLen = len; 
block = source.Substring(i * 128, blockLen); 
byte[] oText = System.Text.Encoding.Default.GetBytes(block); 
BigInteger biText = new BigInteger(oText); 
BigInteger biEnText = biText.modPow(d, n); 
string temp1 = biEnText.ToHexString(); 
temp += temp1; 
len -= blockLen; 
} 
return temp; 
} 

/* 
功能:用指定的公钥(n,e)解密指定字符串source 
*/ 
private string DecryptString(string source, BigInteger e, BigInteger n) 
{ 
int len = source.Length; 
int len1 = 0; 
int blockLen = 0; 
if ((len % 256) == 0) 
len1 = len / 256; 
else 
len1 = len / 256 + 1; 
string block = ""; 
string temp = ""; 
for (int i = 0; i < len1; i++) 
{ 
if (len >= 256) 
blockLen = 256; 
else 
blockLen = len; 
block = source.Substring(i * 256, blockLen); 
BigInteger biText = new BigInteger(block, 16); 
BigInteger biEnText = biText.modPow(e, n); 
string temp1 = System.Text.Encoding.Default.GetString(biEnText.getBytes()); 
temp += temp1; 
len -= blockLen; 
} 
return temp; 
} 

加密过程和解密过程代码如下所示:
/* 
加密过程,其中d、n是RSACryptoServiceProvider生成的D、Modulus 
*/ 
private string EncryptProcess(string source, string d, string n) 
{ 
byte[] N = Convert.FromBase64String(n); 
byte[] D = Convert.FromBase64String(d); 
BigInteger biN = new BigInteger(N); 
BigInteger biD = new BigInteger(D); 
return EncryptString(source, biD, biN); 
} 

/* 
解密过程,其中e、n是RSACryptoServiceProvider生成的Exponent、Modulus 
*/ 
private string DecryptProcess(string source, string e, string n) 
{ 
byte[] N = Convert.FromBase64String(n); 
byte[] E = Convert.FromBase64String(e); 
BigInteger biN = new BigInteger(N); 
BigInteger biE = new BigInteger(E); 
return DecryptString(source, biE, biN); 
}
View Code

 

//改进C#使用RSA私钥加密公钥解密的算法代码及解决特定情况下解密后出现乱码的问题

最近需要对一些数据加密后进行HTTP传输,由于希望对方只能收到数据后解密,而无法知道加密方法以防止伪造,所以选择了一个通过BigInteger类,使用私钥加密,公钥解密的算法。
 
算法是网上找来的,链接如下:
 
http://blog.csdn.net/zhilunchen/archive/2008/09/17/2943158.aspx
 
 一开始使用得挺好,加密解密都正常,但当加密的数据超过了128byte,解密后偶尔会出现乱码,解密失败。
 
通过跟踪发现,这是算法的一个bug,是由于对BigInteger类不当使用产生的。 具体分析如下:
 
先看加密方法:
 

private string EncryptString(string source, BigInteger d, BigInteger n)
        {
            int len = source.Length;
            int len1 = 0;
            int blockLen = 0;
            if ((len % 128) == 0)
                len1 = len / 128;
            else
                len1 = len / 128 + 1;
            string block = "";
            string temp = "";
            for (int i = 0; i < len1; i++)
            {
                if (len >= 128)
                    blockLen = 128;
                else
                    blockLen = len;
                block = source.Substring(i * 128, blockLen);
                byte[] oText = System.Text.Encoding.Default.GetBytes(block);
                BigInteger biText = new BigInteger(oText);
                BigInteger biEnText = biText.modPow(d, n);
                string temp1 = biEnText.ToHexString();
                temp += temp1;
                len -= blockLen;
            }
            return temp;
        }
 
由于RSA算法单次加密只能支持128byte的数据,如果数据长度超过128byte,就会被分割为几段进行加密,最后把加密结果转换为16进制字符串,并连接起来输出结果。
 
一般情况下,128byte的数据,加密后输出的hex字符串应该是256byte,所以对应的解密方法为:把加密后的hex字符串按256byte进行拆分,分别解密,最后得到原文。方法如下:
 

private string DecryptString(string source, BigInteger e, BigInteger n)
        {
            int len = source.Length;
            int len1 = 0;
            int blockLen = 0;
            if ((len % 256) == 0)
                len1 = len / 256;
            else
                len1 = len / 256 + 1;
            string block = "";
            string temp = "";
            for (int i = 0; i < len1; i++)
            {
                if (len >= 256)
                    blockLen = 256;
                else
                    blockLen = len;
                block = source.Substring(i * 256, blockLen);
                BigInteger biText = new BigInteger(block, 16);
                BigInteger biEnText = biText.modPow(e, n);
                string temp1 = System.Text.Encoding.Default.GetString(biEnText.getBytes());
                temp += temp1;
                len -= blockLen;
            }
            return temp;
        }
 
 这个算法一般来讲是没问题的,但问题就在于,对于128byte的数据,BigInteger类输出的加密后的hex字符串,并不一定是256byte。所以,解密的时候按照256byte进行拆分,就会出现字符串拆分不正确,最终导致解密失败,解密出来的结果是乱码。
 
我们来看看BigInteger类的ToHexString()方法,其实现如下:
 

public string ToHexString()
        {
            string result = data[dataLength - 1].ToString("X");

            for (int i = dataLength - 2; i >= 0; i--)
            {
                result += data[i].ToString("X8");
            }

            return result;
        }
 
 对于128byte的BigInteger,此方法返回的结果并不一定是256byte。
 
简单的解决办法,就是把这个方法的第一行,ToString("X")改为ToString("X8"),修改后的方法如下:
 

public string ToHexString()
        {
            string result = data[dataLength - 1].ToString("X8");

            for (int i = dataLength - 2; i >= 0; i--)
            {
                result += data[i].ToString("X8");
            }

            return result;
        }
 
这样改虽然可以解决问题,但属于治标不治本的方法,因为这样改,也不能保证输出的字符串就是256byte, 最靠谱的方法是改进加密方法和解密方法。
 
加密方法的改进:

由于加密后的结果是通过输入16进制字符串进行保存的,输入的结果不可能包含@字符,因此我们可以用@符号来分割每128byte数据的加密结果,解密的时候按照@符号进行分割就不会出错。
 
改进后的加密方法如下:
 

private string EncryptString(string source, BigInteger d, BigInteger n)
        {
            int len = source.Length;
            int len1 = 0;
            int blockLen = 0;
            if ((len % 128) == 0)
                len1 = len / 128;
            else
                len1 = len / 128 + 1;
            string block = "";
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < len1; i++)
            {
                if (len >= 128)
                    blockLen = 128;
                else
                    blockLen = len;
                block = source.Substring(i * 128, blockLen);
                byte[] oText = System.Text.Encoding.Default.GetBytes(block);
                BigInteger biText = new BigInteger(oText);
                BigInteger biEnText = biText.modPow(d, n);
                string temp = biEnText.ToHexString();
                result.Append(temp).Append("@");
                len -= blockLen;
            }
            return result.ToString().TrimEnd('@');
        }
 
 改进后的解密方法如下:
 

private string DecryptString(string source, BigInteger e, BigInteger n)
        {
            StringBuilder result = new StringBuilder();
            string[] strarr1 = source.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < strarr1.Length; i++)
            {
                string block = strarr1[i];
                BigInteger biText = new BigInteger(block, 16);
                BigInteger biEnText = biText.modPow(e, n);
                string temp = System.Text.Encoding.Default.GetString(biEnText.getBytes());
                result.Append(temp);
            }
            return result.ToString();
        }
View Code

 

 

 

=====================================================

  

C#中RSA加密解密和签名与验证的实现    -----  转自:http://blog.csdn.net/llwinnner/article/details/4011936

 

RSA加密算法是一种非对称加密算法。在公钥加密标准和电子商业中RSA被广泛使用。RSA是1977年由罗纳德•李维斯特(Ron Rivest)、阿迪•萨莫尔(Adi Shamir)和伦纳德•阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。.Net的推出,我们能够利用.Net Framework中的类提供的加密服务来保证数据安全。目前应用较为广泛的加密方法是使用RSA算法进行加密。在.Net Framework中与RSA加密算法相关的类主要有两个:RSA 类和RSACryptoServiceProvider 类。按照MSDN的说法RSA 类是“表示 RSA 算法的所有实现均从中继承的基类”,而RSACryptoServiceProvider 类是“使用加密服务提供程序 (CSP) 提供的 RSA 算法的实现执行不对称加密和解密”。另外,“表示 RSA 算法的标准参数”的RSAParameters 结构也是很重要的,它保存了RSA算法的参数。

 

//这里具体讲述一下在C#中如何使用框架提供的RSA算法来对我们的信息加密、签名、验证签名、解密的这个几个步骤的实现
        using System.Security.Cryptography;
        using System.Management;
        using Microsoft.Win32;
        /// <summary>
        /// 生成公私钥
        /// </summary>
        /// <param name="PrivateKeyPath"></param>
        /// <param name="PublicKeyPath"></param>
        public void RSAKey(string PrivateKeyPath, string PublicKeyPath)
        {
            try
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                this.CreatePrivateKeyXML(PrivateKeyPath, provider.ToXmlString(true));
                this.CreatePublicKeyXML(PublicKeyPath, provider.ToXmlString(false));
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        /// <summary>
        /// 对原始数据进行MD5加密
        /// </summary>
        /// <param name="m_strSource">待加密数据</param>
        /// <returns>返回机密后的数据</returns>
        public string GetHash(string m_strSource)
        {
            HashAlgorithm algorithm = HashAlgorithm.Create("MD5");
            byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(m_strSource);
            byte[] inArray = algorithm.ComputeHash(bytes);
            return Convert.ToBase64String(inArray);
        }
        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="xmlPublicKey">公钥</param>
        /// <param name="m_strEncryptString">MD5加密后的数据</param>
        /// <returns>RSA公钥加密后的数据</returns>
        public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
        {
            string str2;
            try
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                provider.FromXmlString(xmlPublicKey);
                byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);
                str2 = Convert.ToBase64String(provider.Encrypt(bytes, false));
            }
            catch (Exception exception)
            {
                throw exception;
            }
            return str2;
        }
        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="xmlPrivateKey">私钥</param>
        /// <param name="m_strDecryptString">待解密的数据</param>
        /// <returns>解密后的结果</returns>
        public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
        {
            string str2;
            try
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                provider.FromXmlString(xmlPrivateKey);
                byte[] rgb = Convert.FromBase64String(m_strDecryptString);
                byte[] buffer2 = provider.Decrypt(rgb, false);
                str2 = new UnicodeEncoding().GetString(buffer2);
            }
            catch (Exception exception)
            {
                throw exception;
            }
            return str2;
        }
        /// <summary>
        /// 对MD5加密后的密文进行签名
        /// </summary>
        /// <param name="p_strKeyPrivate">私钥</param>
        /// <param name="m_strHashbyteSignature">MD5加密后的密文</param>
        /// <returns></returns>
        public string SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature)
        {
            byte[] rgbHash = Convert.FromBase64String(m_strHashbyteSignature);
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPrivate);
            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
            formatter.SetHashAlgorithm("MD5");
            byte[] inArray = formatter.CreateSignature(rgbHash);
            return Convert.ToBase64String(inArray);
        }
        /// <summary>
        /// 签名验证
        /// </summary>
        /// <param name="p_strKeyPublic">公钥</param>
        /// <param name="p_strHashbyteDeformatter">待验证的用户名</param>
        /// <param name="p_strDeformatterData">注册码</param>
        /// <returns></returns>
        public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData)
        {
            try
            {
                byte[] rgbHash = Convert.FromBase64String(p_strHashbyteDeformatter);
                RSACryptoServiceProvider key = new RSACryptoServiceProvider();
                key.FromXmlString(p_strKeyPublic);
                RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
                deformatter.SetHashAlgorithm("MD5");
                byte[] rgbSignature = Convert.FromBase64String(p_strDeformatterData);
                if (deformatter.VerifySignature(rgbHash, rgbSignature))
                {
                    return true;
                }
                return false;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 获取硬盘ID
        /// </summary>
        /// <returns>硬盘ID</returns>
        public string GetHardID()
        {
            string HDInfo = "";
            ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");
            ManagementObjectCollection moc1 = cimobject1.GetInstances();
            foreach (ManagementObject mo in moc1)
            {
                HDInfo = (string)mo.Properties["Model"].Value;
            }
            return HDInfo;
        }
        /// <summary>
        /// 读注册表中指定键的值
        /// </summary>
        /// <param name="key">键名</param>
        /// <returns>返回键值</returns>
        private string ReadReg(string key)
        {
            string temp = "";
            try
            {
                RegistryKey myKey = Registry.LocalMachine;
                RegistryKey subKey = myKey.OpenSubKey(@"SOFTWARE/JX/Register");
 
                temp = subKey.GetValue(key).ToString();
                subKey.Close();
                myKey.Close();
                return temp;
            }
            catch (Exception)
            {
                throw;//可能没有此注册项;
            }
 
        } 
        /// <summary>
        /// 创建注册表中指定的键和值
        /// </summary>
        /// <param name="key">键名</param>
        /// <param name="value">键值</param>
        private void WriteReg(string key, string value)
        {
            try
            {
                RegistryKey rootKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");
                rootKey.SetValue(key, value);
                rootKey.Close();
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 创建公钥文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="publickey"></param>
        public void CreatePublicKeyXML(string path, string publickey)
        {
            try
            {
                FileStream publickeyxml = new FileStream(path, FileMode.Create);
                StreamWriter sw = new StreamWriter(publickeyxml);
                sw.WriteLine(publickey);
                sw.Close();
                publickeyxml.Close();
            }
            catch
            {
                throw;
            }
        }
        /// <summary>
        /// 创建私钥文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="privatekey"></param>
        public void CreatePrivateKeyXML(string path, string privatekey)
        {
            try
            {
                FileStream privatekeyxml = new FileStream(path, FileMode.Create);
                StreamWriter sw = new StreamWriter(privatekeyxml);
                sw.WriteLine(privatekey);
                sw.Close();
                privatekeyxml.Close();
            }
            catch
            {
                throw;
            }
        }
        /// <summary>
        /// 读取公钥
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public string ReadPublicKey(string path)
        {
            StreamReader reader = new StreamReader(path);
            string publickey = reader.ReadToEnd();
            reader.Close();
            return publickey;
        }
        /// <summary>
        /// 读取私钥
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public string ReadPrivateKey(string path)
        {
            StreamReader reader = new StreamReader(path);
            string privatekey = reader.ReadToEnd();
            reader.Close();
            return privatekey;
        }
        /// <summary>
        /// 初始化注册表,程序运行时调用,在调用之前更新公钥xml
        /// </summary>
        /// <param name="path">公钥路径</param>
        public void InitialReg(string path)
        {
            Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");
            Random ra = new Random();
            string publickey = this.ReadPublicKey(path);
            if (Registry.LocalMachine.OpenSubKey(@"SOFTWARE/JX/Register").ValueCount <= 0)
            {
                this.WriteReg("RegisterRandom", ra.Next(1,100000).ToString());
                this.WriteReg("RegisterPublicKey", publickey);
            }
            else
            {
                this.WriteReg("RegisterPublicKey", publickey);
            }
        } 
View Code

 

如果是要对发送的消息进行加密和解密,加密时用公钥,解密时用私钥,即使密文被窃取也无法破解。
如果是要对软件进行注册,生成注册码,则服务端将用户的硬盘号用私钥加密,客户端用公钥解密,解密后将客户端的硬盘号进行MD5加密,将得到的结果和解密后的结果进行比较,如果相同,说明是注册用户,否则为非注册用户。

 

 

 

===================================================

C#RSA算法应用    ---    转自:http://blog.csdn.net/ozeroo/article/details/1581079

//首先将字符串转换为字节数组,这与编码有关
     string str=textBox1.Text;
   
      byte[]   bytes = Encoding.ASCII.GetBytes(str);
    
    //选择签名方式,如:RSA和DSA
  
   DSACryptoServiceProvider dsac = new DSACryptoServiceProvider();
      byte[]  sign = dsac.SignData( bytes );

   ASCIIEncoding encoding = new ASCIIEncoding( ); 
   textBox2.Text  = encoding.GetString( bytes ); 
   ASCIIEncoding encoding2 = new ASCIIEncoding( ); 
   textBox3.Text  = encoding.GetString( sign ); 
   
   //sign 便是出来的签名结果
  
   //进行认证
    DSACryptoServiceProvider dsac2 = new DSACryptoServiceProvider();

    dsac2.FromXmlString(dsac.ToXmlString(false));

  
    bool ver = dsac2.VerifyData( bytes  ,sign);

     if(ver)
        {
  
               MessageBox.Show("Pass!");
  
        }
View Code

 

 

 

=======================================================================

 

C#实现的RSA加解密算法     ---    转自:http://ssh-2009-126-com.iteye.com/blog/470214

//c#实现代码

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Security.Cryptography;  
using System.IO;  
using System.Xml;  
  
namespace MyRSA  
{  
    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);  
            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);  
            return provider1;  
        }  
  
        private byte[] ReadChild(XmlElement parent, string name)  
        {  
            XmlElement element1 = (XmlElement)parent.SelectSingleNode(name);  
            return hexToBytes(element1.InnerText);  
        }  
  
        private 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);  
        }  
    }  
}  
View Code

 

//测试代码

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Security.Cryptography;  
  
namespace MyRSA  
{  
    class Program  
    {  
         
        static void Main(string[] args)  
        {  
            Console.WriteLine("\n encrypt and de_encrypt test:\n===========================");  
              
            RSAUtil rsa = new RSAUtil();  
  
            //rsa.CreateRSAKey()  
  
            Console.WriteLine("Please input a string\n");  
  
            string mingwen = Console.ReadLine();  
  
            string miwen = rsa.EnCrypt(mingwen);  
  
            string jiemiwen=rsa.DoEncrypt(miwen);  
  
            Console.WriteLine("Ming Wen is :"+mingwen+"\n");  
  
            Console.WriteLine("Mi Wen is :"+miwen+"\n");  
  
            Console.WriteLine("Jie Mi hou is :"+jiemiwen+"\n");  
  
            Console.ReadLine();  
        }  
    }  
}
View Code

 

 

 

posted on 2014-01-02 13:58  RJ  阅读(1438)  评论(0编辑  收藏  举报

导航