流程是这样的,我先需要在证书里面读出公钥(已经实现),然后把需要加密的数据和公钥放到RSA里面加密。现在实现了在证书里提取公钥,但是我不知道怎么把这个公钥放到RSA里面去加密。以下是我在MSDN里看的代码,里面没有描述怎么用公钥对数据加密,请高手指点,如果有朋友做这个加密方面的可以加我QQ:1158281,大家一起讨论下。static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
{
try
{    
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.ImportParameters(RSAKeyInfo);



RijndaelManaged RM = new RijndaelManaged();
return RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
}

catch(CryptographicException e)
{
Console.WriteLine(e.Message); return null;
} }
static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo,bool DoOAEPPadding)
{
try
{
//Create a new instance of RSACryptoServiceProvider.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); //Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(RSAKeyInfo);

//Decrypt the passed byte array and specify OAEP padding.  
//OAEP padding is only available on Microsoft Windows XP or
//later.  
return RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
}
//Catch and display a CryptographicException  
//to the console.
catch(CryptographicException e)
{
Console.WriteLine(e.ToString()); return null;
} }
private void button1_Click(object sender, System.EventArgs e)
{
string certfile = @"e:\srvcert.crt";

X509Certificate cert = X509Certificate.CreateFromCertFile(certfile);
byte[] PublicKey = cert.GetPublicKey();//证书公钥
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
byte[] privatekey = Encoding.Default.GetBytes("aaaaaa"); byte[] dataToEncrypt = Encoding.Default.GetBytes("Data to Encrypt");
byte[] encryptedData;
byte[] decryptedData;

encryptedData = RSAEncrypt(dataToEncrypt,RSA.ExportParameters(true), false); decryptedData = RSADecrypt(encryptedData,RSA.ExportParameters(true), false);
}

解决方案 »

  1.   

    为什么不用C#自带的RSA加密类?
      

  2.   

    很明显,代码错误
     byte[] PublicKey = cert.GetPublicKey();//证书公钥
    取到了公钥,但没有在任何地方使用这个公钥,还有对应的私钥呢,在那里出现了?
    我看楼主先研究一下加密的原理再说吧。
      

  3.   

    原文见:http://www.cnblogs.com/lkcn/
    代码见原文本人目前在做一个关于“数字签名”的项目,在网上查资料,感觉这方面的都非常的少,一般都是讲RSA的算法,或者“数字签名”的原理,完全是浪费时间。我经过摸索,小有进展,初步实现功能。今天写出来,希望能给以后的做这个的朋友提供个方便。还有一件事,在我查资料的时候也遇见很多朋友在做这个项目,但是我感觉他们都在进入了几个误区。我先把这几个误区说说,以免大家以后走错方向。说得不对的地方希望大家能批评指正,毕竟本人能力有限(但是不要骂我) ^_^ 误区一:大家对公钥私钥区分得太.......(我还找不到形容来形容了.... ),就太死板了吧。其实当你把公钥保密不公开的时候,公钥就是私钥了;当你把私钥公开的时候,私钥也是公钥了。没必要记得这么死的(个人意见)。
    误区二:对RSA算法的原理理解不够,实际上所谓的公钥和私钥只是RSA算法(说穿了RSA就是个数学方程式)的参数(未知数),比如 X+Y+M=Z,X就可以说是私钥,Y就可以说是公钥,M就是需要加密的内容,Z就是加密后的密文,当然RSA中不可能只有X和Y两个未知数的,所以就经常有朋友问,到底X是私钥还是Y是私钥(嘻嘻... 我也问过)。其实这个就要取决于你用在时候,什么地方了。
    误区三:对Security.Cryptography命名空间不熟悉。“数字签名”一般的做法是:A先计算出文件M的HASH码,再对HASH码进行加密(这个步骤就是签名),再把M(文件M不要加密,第三方可以查阅)和加密后的HASH码传送给B,B再用A的公钥来解密刚才得到的加密HASH码,如果能解密,那就说明这个文件是A发的,具有法律效应。再计算出得到的文件M的HASH码,再和刚才解密出来的HASH码比较(这个步骤叫验证签名),如果一致就说明文件M在传输过程中没有被修改。但是在C#中需要解密RSA,就必须提供公钥和私钥,当然这和我们的现实不符,因为A不可能把他的私钥给B。许多人就是在这里难住了。其实在C#的Security.Cryptography命名空间中有RSAPKCS1SignatureFormatter 和RSAPKCS1SignatureDeformatter 两个方法或者说是对象。前者用来对HASH进行加密(签名),后者用来验证签名,用这个验证就只需要A的公钥就行了。在C#中,签名就是这个两个专用的方法,不是用RSA普通的加密解密。下面我就贴出我的代码,我的公钥和私钥就是从两个文件PublicKey.xml、PrivateKey.xml中读取出来,相当于是现实中的指定公钥和私钥;再验证时我为了方便直接验证的A计算出的HASH码,现实中应该是由B重新计算出文件M的HASH码(这个大家明白就行了^_^)。
      

  4.   

    jimh(Jimmy):我就是不知道怎么把这个私钥放到RSA里面去阿。
      

  5.   

    JadyWang(最近比较矛盾):我是用的net提供的类
      

  6.   

    原文见:http://www.cnblogs.com/lkcn/
    代码见原文
      

  7.   

    我加密现在是这样写的:
    RSAParameters RSAKeyInfo = new RSAParameters();
    RSAKeyInfo.Modulus = PublicKey;
    RSAKeyInfo.Exponent = dataToEncrypt; RSA.ImportParameters(RSAKeyInfo);


    RijndaelManaged RM = new RijndaelManaged(); encryptedData = RSA.Encrypt(RM.Key,false);
    但是每次加密出来的结果都不一样。请高手解答。
      

  8.   

    using System;
    using System.IO;
    using System.Text;
    using System.Security.Cryptography;/// <summary>
    /// 一个简单的使用.NET非对称加密算法的例子
    /// 本例的程序很简单,仅用于说明如何在.NET里面使用非对称(RSA)算法。
    /// Kwanhong 2005.9
    /// </summary>
    class Class1
    {
     public static void Main(string[] args)
     {
      Class1 c=new Class1();
      c.StartDemo();
     } public void StartDemo()
     {
      //RSA的加解密过程:
      //  有 rsa1 和 rsa2 两个RSA对象。
      //  现在要 rsa2 发送一段信息给 rsa1, 则先由 rsa1 发送“公钥”给 rsa2
      //  rsa2 获取得公钥之后,用来加密要发送的数据内容。
      //  rsa1 获取加密后的内容后,用自己的私钥解密,得出原始的数据内容。  RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider();
      RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider();  string publickey;
      publickey=rsa1.ToXmlString(false);  //导出 rsa1 的公钥  string plaintext;
      plaintext="你好吗?这是用于测试的字符串。";  //原始数据
      Console.WriteLine("原始数据是:\n{0}\n",plaintext);  rsa2.FromXmlString(publickey); //rsa2 导入 rsa1 的公钥,用于加密信息  //rsa2开始加密
      byte[] cipherbytes;
      cipherbytes=rsa2.Encrypt(
       Encoding.UTF8.GetBytes(plaintext),
       false);  /*//////////////////////////////////////////////*/
      Console.WriteLine("加密后的数据是:");
      for(int i=0; i< cipherbytes.Length; i++)
      {
       Console.Write("{0:X2} ",cipherbytes[i]);
      }
      Console.WriteLine("\n");
      /*//////////////////////////////////////////////*/  //rsa1开始解密
      byte[] plaintbytes;
      plaintbytes = rsa1.Decrypt(cipherbytes,false);  Console.WriteLine("解密后的数据是:");
      Console.WriteLine(Encoding.UTF8.GetString(plaintbytes));  Console.ReadLine();
     }
    }
      

  9.   

    楼主需要保存公匙和私匙,可以像metababy(花生)说的那样保存为xml,RSA有相关方法,在几个基础上用私匙加密,用公匙解密,公匙和私匙是配对的,一一对应的。
      

  10.   

    楼主,jxufewbt的方法行不?你在线等的,现在也没个反应。。@@