加密解密时遇到的"不正确的数据"以及"要解密的数据长度无效"问题解决方案

原创 2006年06月21日 10:00:00
这两天一直在为文件加密解密时,由于关闭数据转换链接流CryptoStream或者使用FlushFinalBlock时出现的
“不正确的数据”和“要解密的数据长度无效”异常而烦恼,到现在也没弄懂具体是什么问题,如果有哪位高人能指点一下,在下不胜感激。
    不过问题最终还是解决了,改变了加密和解密时的读取和写入的方式来解决了,最初都是直接对文件流操作,昨晚把它们修改为直接操作内存流。下面是操作文件流和操作内存流代码的对比:

直接操作文件流---加密:

程序代码:

/// <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);
    }
}

上面的文件加密方法在加密的时候没有任何问题,但是同样的,稍微修改下,下面是对应的解密的方法:
程序代码:

/// <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;
}

相关文章推荐

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

RSA 加密解密-不正确的数据2
  • hugo20
  • hugo20
  • 2016年08月10日 22:54
  • 1039

对称加密DES和TripleDES

一、 对称加密 对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码)。因此,通信双方都...

对称加密解密类

可以对url或者是url参数进行加密解密的帮助类。
  • itmaxin
  • itmaxin
  • 2014年02月25日 10:08
  • 1555

关于遇到的 C# DES 解密出现 "CryptographicException:不正确的数据"

tomcat中的加密程序需要换到iis中,用起了 C#中的 DESCryptoServiceProvider,上网找了些相关流程写了个类,感觉比java的程序精简。 但测试中发现异常,同一次测试中,...

.Net使用DES解密发生“数据不正确”的错误

DES解密,异常消息提示数据不正确,一般是由于加密阶段,没有将密文的流数据完整输出...

C#与Java同步加密解密DES算法

在实际项目中,往往前端和后端使用不同的语言。比如使用C#开发客户端,使用Java开发服务器端。有时出于安全性考虑需要将字符加密传输后,由服务器解密获取。本文介绍一种采用DES算法的C#与Java同步加...

最简单的字符串加密C#实现-移位加密

/*   Filename: encrypt_string.cs  Author : zhanghua  Date  : 2005-08-11  Fuction : input a strig  an...

关于AES在Linux下加密解密出错问题解决方案

现象描述: windows 上加解密正常, linux 上加密正常,解密时发生如下异常 : javax.crypto.BadPaddingException: ...

RSA 分段加解密-解决“不正确的长度”的数据

RSA 分段加解密-解决“不正确的长度”的异常
  • hugo20
  • hugo20
  • 2016年08月10日 22:15
  • 3812

java文件预览及加密解密的部分问题及解决方案

经过半个月的代码编写,再经过半个月的测试,文件加密解密及预览功能基本上全部实现了,当然,一些小的细节还有待修改。 遇到最大的麻烦还是:操作平台的切换导致的一系列问题,本地测试完全不bug,部署...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:加密解密时遇到的"不正确的数据"以及"要解密的数据长度无效"问题解决方案
举报原因:
原因补充:

(最多只允许输入30个字)