RSA 加密解密-不正确的数据2

源码如下:
 /// <summary>
  /// 解密给定的字符串
  /// </summary>
  /// <param name='str'>要解密的字符</param>
  /// <returns></returns>
  public string DecryptString(string str)
  {
       byte[] ivb=Encoding.ASCII.GetBytes(this.iv);
       byte[] keyb=Encoding.ASCII.GetBytes(this.EncryptKey);
       byte[] toDecrypt=this.EncodingMode.GetBytes(str);
       byte[] deCrypted=new byte[toDecrypt.Length];
       ICryptoTransform deCryptor=des.CreateDecryptor(keyb,ivb);
       MemoryStream msDecrypt=new MemoryStream(toDecrypt);
       CryptoStream csDecrypt=new CryptoStream(msDecrypt,deCryptor,CryptoStreamMode.Read);
       try
       {
        csDecrypt.Read(deCrypted,0,deCrypted.Length);
       }
       catch(Exception err)
       {
        throw new ApplicationException(err.Message);
       }
       finally
       {
        try
        {
         msDecrypt.Close();
         csDecrypt.Close();
        }
        catch{;}
       }
       return this.EncodingMode.GetString(deCrypted);
  }
为什么会出现这个问题?
解决方案 »
  1. cvm
  2. //名称空间       
      using     System;       
      using     System.Security.Cryptography;       
      using     System.IO;       
      using     System.Text;       
          
      //方法       
      //加密方法       
      public         string     Encrypt(string     pToEncrypt,     string     sKey)       
      {       
                            DESCryptoServiceProvider     des     =     new     DESCryptoServiceProvider();       
                            //把字符串放到byte数组中       
                                        //原来使用的UTF8编码,我改成Unicode编码了,不行       
                            byte[]     inputByteArray     =     Encoding.Default.GetBytes(pToEncrypt);       
                            //byte[]     inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt);       
          
                            //建立加密对象的密钥和偏移量       
                            //原文使用ASCIIEncoding.ASCII方法的GetBytes方法       
                            //使得输入密码必须输入英文文本       
                            des.Key     =     ASCIIEncoding.ASCII.GetBytes(sKey);       
                            des.IV     =     ASCIIEncoding.ASCII.GetBytes(sKey);       
                            MemoryStream     ms     =     new     MemoryStream();       
                            CryptoStream     cs     =     new     CryptoStream(ms,     des.CreateEncryptor(),CryptoStreamMode.Write);       
                            //Write     the     byte     array     into     the     crypto     stream       
                            //(It     will     end     up     in     the     memory     stream)       
                            cs.Write(inputByteArray,     0,     inputByteArray.Length);       
                            cs.FlushFinalBlock();       
                            //Get     the     data     back     from     the     memory     stream,     and     into     a     string       
                            StringBuilder     ret     =     new     StringBuilder();       
                            foreach(byte     b     in     ms.ToArray())       
                                                    {       
                                                    //Format     as     hex       
                                                    ret.AppendFormat("{0:X2}",     b);       
                                                    }       
                            ret.ToString();       
                            return     ret.ToString();       
      }       
          
      //解密方法       
      public         string     Decrypt(string     pToDecrypt,     string     sKey)       
      {       
                            DESCryptoServiceProvider     des     =     new     DESCryptoServiceProvider();       
          
                            //Put     the     input     string     into     the     byte     array       
                            byte[]     inputByteArray     =     new     byte[pToDecrypt.Length     /     2];       
                            for(int     x     =     0;     x     <     pToDecrypt.Length     /     2;     x++)       
                            {       
                                                int     i     =     (Convert.ToInt32(pToDecrypt.Substring(x     *     2,     2),     16));       
                                    inputByteArray[x]     =     (byte)i;       
                            }       
          
                            //建立加密对象的密钥和偏移量,此值重要,不能修改       
                            des.Key     =     ASCIIEncoding.ASCII.GetBytes(sKey);       
                            des.IV     =     ASCIIEncoding.ASCII.GetBytes(sKey);       
                            MemoryStream     ms     =     new     MemoryStream();       
                            CryptoStream     cs     =     new     CryptoStream(ms,     des.CreateDecryptor(),CryptoStreamMode.Write);       
                            //Flush     the     data     through     the     crypto     stream     into     the     memory     stream       
                            cs.Write(inputByteArray,     0,     inputByteArray.Length);       
                            cs.FlushFinalBlock();       
          
                            //Get     the     decrypted     data     back     from     the     memory     stream       
                            //建立StringBuild对象,CreateDecrypt使用的是流对象,必须把解密后的文本变成流对象       
                            StringBuilder     ret     =     new     StringBuilder();       
                                  
                            return     System.Text.Encoding.Default.GetString(ms.ToArray());       
      }  
    试试行不行!
      

  3. 直接操作文件流---加密:程序代码: /// <summary>
    /// 文件加密
    /// </summary>
    /// <param name="inFileName">需要加密的文件(文件的完整路径)</param>
    /// <param name="outFileName">加密后的文件(文件的完整路径)</param>
    /// <param name="sAlgorithm">对称算法实例</param>
    /// <returns>bool</returns>
    private bool EncryptFile(string InFileName, string OutFileName, SymmetricAlgorithm sAlgorithm)
    {
        try
        {
     //创建加密文件流
     FileStream inFileStream = new FileStream(InFileName, FileMode.Open, FileAccess.Read);
     FileStream outFileStream = new FileStream(OutFileName, FileMode.OpenOrCreate, FileAccess.Write); //锁定被加密文件
     inFileStream.Lock(0, inFileStream.Length);
     //设定加密后文件的初始长度
     outFileStream.SetLength(0); long fileLength = inFileStream.Length;  //文件的总字节数组长度
     byte[] bytein = new byte[100];        //每次以100个字节读取需要加密的文件
     long readedlen = 0;                    //记录已被读取的字节位置
     int len = 0;                    //每次写入的字节长度
     CryptoStream encStream = new CryptoStream(outFileStream, sAlgorithm.CreateEncryptor(this.KeyValue, this.IVValue), CryptoStreamMode.Write);
     try
     {
         while (readedlen < fileLength)
         {
      len = inFileStream.Read(bytein, 0, 100);//从输入流中读取100字节数组数据到bytein缓冲区
      encStream.Write(bytein, 0, 100);
      readedlen = readedlen + len;
         }
         outFileStream.Flush();
         inFileStream.Flush();
         encStream.Flush();
         return true;
     }
     catch (Exception error)
     {
         throw (error);
     }
     finally
     {
         inFileStream.Unlock(0, inFileStream.Length);
         encStream.Close();
         inFileStream.Close();
         outFileStream.Close();
     }
        }
        catch (Exception error)
        {
     throw (error);
        }
    }
     
      

  4. 上面的文件加密方法在加密的时候没有任何问题,但是同样的,稍微修改下,下面是对应的解密的方法:
    程序代码: /// <summary>
    /// 文件解密
    /// </summary>
    /// <param name="inFileName">需要解密的文件(文件的完整路径)</param>
    /// <param name="outFileName">解密后的文件(文件的完整路径)</param>
    /// <param name="sAlgorithm">对称算法实例</param>
    /// <returns>bool</returns>
    public bool DecryptFile(string InFileName, string OutFileName, SymmetricAlgorithm sAlgorithm)
    {
        try
        {
     //创建解密文件流
     FileStream inFileStream = new FileStream(InFileName, FileMode.Open, FileAccess.Read);
     FileStream outFileStream = new FileStream(OutFileName, FileMode.OpenOrCreate, FileAccess.Write);
     //设定加密后文件的初始长度
     outFileStream.SetLength(0);
     long fileLength = inFileStream.Length;  //文件的总字节数组长度
     byte[] bytein = new byte[100];        //每次以100个字节读取需要加密的文件
     long readedlen = 0;                    //记录已被读取的字节位置
     int len = 0;                    //每次写入的字节长度
     CryptoStream encStream = new CryptoStream(outFileStream, sAlgorithm.CreateDecryptor(this.KeyValue, this.IVValue), CryptoStreamMode.Write);
     try
     {
         while (readedlen < fileLength)
         {
      len = inFileStream.Read(bytein, 0, 100);//从输入流中读取100字节数组数据到bytein缓冲区
      encStream.Write(bytein, 0, 100);
      readedlen = readedlen + len;
         }
         outFileStream.Flush();
         inFileStream.Flush();
         encStream.FlushFinalBlock(); //加了这一句,有的时候就会出现异常,不知道为什么  
         return true; 
     }
     catch (Exception error)
     {
         throw (error);
     }
     finally
     {
         encStream.Close(); //加了这一句,有的时候就会出现异常,不知道为什么  
         inFileStream.Close();
         outFileStream.Close();
     }
        }
        catch (Exception error)
        {
     throw (error);
        }
    } 上面的解密方法中,红颜色标识的两行代码,在有些情况下就会提示我上面所说的两种异常,到现在我唯一能稍微明白的是可能因为我加密后立即解密就会出现上面的异常情况,因为我查了好多资料都没有提示有这两种异常的出现。下面是我加密解密方法我改成操作内存流的代码,下面的代码能正常执行。
    加密:
    程序代码: /// <summary>
    /// 文件加密
    /// </summary>
    /// <param name="inFileName">需要加密的文件(文件的完整路径)</param>
    /// <param name="outFileName">加密后的文件(文件的完整路径)</param>
    /// <param name="sAlgorithm">对称算法实例</param>
    /// <returns>bool</returns>
    private bool EncryptFile(string InFileName, string OutFileName, SymmetricAlgorithm sAlgorithm)
    {
        //将文件内容读取到字节数组
        FileStream inFileStream = new FileStream(InFileName, FileMode.Open, FileAccess.Read);
        byte[] sourceByte       = new byte[inFileStream.Length];
        inFileStream.Read(sourceByte, 0, sourceByte.Length);
        inFileStream.Flush();
        inFileStream.Close();    MemoryStream encryptStream  = new MemoryStream();
        CryptoStream encStream      = new CryptoStream(encryptStream, sAlgorithm.CreateEncryptor(), CryptoStreamMode.Write);
        try
        {
     //利用链接流加密源字节数组
     encStream.Write(sourceByte, 0, sourceByte.Length);
     encStream.FlushFinalBlock(); //将字节数组信息写入指定文件
     FileStream outFileStream= new FileStream(OutFileName, FileMode.OpenOrCreate, FileAccess.Write);
     BinaryWriter bWriter    = new BinaryWriter(outFileStream);
     bWriter.Write(encryptStream.ToArray());
     encryptStream.Flush(); bWriter.Close();
     encryptStream.Close();
        }
        catch (Exception error)
        {
     throw (error);
        }
        finally
        {
     encryptStream.Close();
     encStream.Close();
        }
        return true;
    }
     
    对应的解密方法:
    程序代码: /// <summary>
    /// 文件解密
    /// </summary>
    /// <param name="inFileName">需要解密的文件(文件的完整路径)</param>
    /// <param name="outFileName">解密后的文件(文件的完整路径)</param>
    /// <param name="sAlgorithm">对称算法实例</param>
    /// <returns>bool</returns>
    public bool DecryptFile(string InFileName, string OutFileName, SymmetricAlgorithm sAlgorithm)
    {    //读取被加密文件到字节数组
        FileStream encryptFileStream= new FileStream(InFileName, FileMode.Open, FileAccess.Read);
        byte[] encryptByte          = new byte[encryptFileStream.Length];
        encryptFileStream.Read(encryptByte, 0, encryptByte.Length);
        encryptFileStream.Flush();
        encryptFileStream.Close();
        
        MemoryStream decryptStream  = new MemoryStream();
        CryptoStream encStream      = new CryptoStream(decryptStream, sAlgorithm.CreateDecryptor(), CryptoStreamMode.Write);
        try
        {
     encStream.Write(encryptByte, 0, encryptByte.Length);
     encStream.FlushFinalBlock(); byte[] decryptByte          = decryptStream.ToArray();
     FileStream decryptFileStream= new FileStream(OutFileName, FileMode.OpenOrCreate, FileAccess.Write);
     BinaryWriter bWriter        = new BinaryWriter(decryptFileStream, Encoding.GetEncoding("GB18030"));
     bWriter.Write(decryptByte);
     decryptFileStream.Flush(); bWriter.Close();
     decryptFileStream.Close();
        }
        catch (Exception error)
        {
     throw (error);
        }
        finally
        {
     decryptStream.Close();
     encStream.Close();
        }    return true;
    }
     
      

  5. using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Security.Cryptography;
    using System.IO;namespace DES加密解密
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                this.textBox2.Text = DESEncrypt("" + this.textBox1.Text.ToString().Trim() + "");
            }        //加密
            public string DESEncrypt(string pToEncrypt)
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                try
                {
                    byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
                      //密匙和偏移量
                    byte[] kkk = new byte[] { 0x16, 0x09, 0x14, 0x15, 0x07, 0x01, 0x05, 0x08 };
                    byte[] iivv = new byte[] { 0x08, 0x05, 0x01, 0x07, 0x15, 0x14, 0x09, 0x16 };
                    des.Key = kkk;
                    des.IV = iivv;                MemoryStream ms = new MemoryStream();
                    CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    StringBuilder ret = new StringBuilder();
                    foreach (byte b in ms.ToArray())
                    {
                        ret.AppendFormat("{0:X2}", b);
                    }
                    ret.ToString();
                    return ret.ToString();
                }
                catch
                {
                    return "";
                }        }        private void button2_Click(object sender, EventArgs e)
            {
                this.textBox3.Text = DESDecrypt("" + this.textBox2.Text.ToString().Trim() + "");
            }
             //解密
            public string DESDecrypt(string pToDecrypt)
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                try
                {
                    byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
                    for (int x = 0; x < pToDecrypt.Length / 2; x++)
                    {
                        int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                        inputByteArray[x] = (byte)i;
                    }                byte[] kkk = new byte[] { 0x16, 0x09, 0x14, 0x15, 0x07, 0x01, 0x05, 0x08 };
                    byte[] iivv = new byte[] { 0x08, 0x05, 0x01, 0x07, 0x15, 0x14, 0x09, 0x16 };
                    des.Key = kkk;
                    des.IV = iivv;                MemoryStream ms = new MemoryStream();
                    CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();                StringBuilder ret = new StringBuilder();                return System.Text.Encoding.Default.GetString(ms.ToArray());
                }
                catch
                {
                    return "";
                }
            }
     
            
        }
    }
      

  6. 哈,新来乍到。这个我刚才自己试了一个多钟头搞明白了,记住不断把能Flush的CryptoStream赶紧Flush了,然后再赶紧close就行了。
    原理不明。似乎涉及内存问题。而且微软自己的例子里还要把key的内存部分锁住。
    希望处女贴能给大家点帮助。
      

  7. 虽然是2007年的帖子了,但考虑到依然会有人搜索到这帖,为了帮助像我这样搜索到儿还无能为力的人,就把解决问题的方法跟一下吧:
    http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/f97717cb-4e23-48cd-b078-e33348f75bed
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值