这两天一直在为文件加密解密时,由于关闭数据转换链接流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;
}

转载于:https://www.cnblogs.com/my-blog/archive/2009/03/03/1402246.html

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

  1. 使用xilinx7系列FPGA对比特流进行加密认证时如何确保密钥已经正确加载到FPGA中

    使用xilinx7系列FPGA对比特流进行加密认证时如何确保密钥已经正确加载到FPGA中 序言 通常使用FPGA时,默认是不对比特流进行加密认证的.XIlinx 7系列FPGA支持采用AES-256- ...

  2. Des解密时向量超过8个字符

    @Des解密时向量超过8个字符 项目跟外围系统交换数据,对方系统要求只能用Des加密方式.我们这边是数据接收方,所以只解密就可以.对方给出的密钥和向量信息如下: 加密数据:SsgnnTYQEcLluR ...

  3. DESUtils 加解密时 Given final block not properly padded bug小记

    事情的经过是这个样子的...... 先说说问题是怎么出现的.根据客户需求,需要完成一个一键登录的功能,于是我的项目中就诞生了DesUtil,但是经过上百次用户测试,发现有一个用户登录就一直报错!难道又 ...

  4. java android rsa加密解密_Android RSA数据加密与Java服务端RSA私钥解密出错问题

    1. 出错描述:服务RSA解密抛出javax.crypto.BadPaddingException: Decryption error 2.出错原因:Android系统使用的虚拟机(dalvik)跟S ...

  5. 使用对称加/解密时,要注意考虑填充

    原问题1: 加密时是直接写入文件的,解密时是一边读加密后的文件,一边解.对于有的字符串就对,有的就不对,我怀疑那个DES加密的类有问题. public static void DesEncrypt(S ...

  6. Java 进行 RSA 加解密时不得不考虑到的那些事儿

    1. 加密的系统不要具备解密的功能,否则 RSA 可能不太合适 公钥加密,私钥解密.加密的系统和解密的系统分开部署,加密的系统不应该同时具备解密的功能,这样即使黑客攻破了加密系统,他拿到的也只是一堆无 ...

  7. Php使用selenium爬虫,selenium,python爬虫_使用selenium爬取网站时输出结果不正确,selenium,python爬虫 - phpStudy...

    使用selenium爬取网站时输出结果不正确 网站链接:http://www.ncbi.nlm.nih.gov/pubmed?term=(%222013%22%5BDate%20-%20Publica ...

  8. Python - 遍历列表时删除元素的正确做法

    Python-遍历列表时删除元素的正确做法 一.问题描述 因为删除元素后,整个列表的元素会往前移动,而i却是在最初就已经确定了,是不断增大的,所以并不能得到想要的结果. 问题现象如下: a = [1, ...

  9. mysql limit 5 5 正确_MySql 5.7 同时使用order by和limit时结果集不正确的问题

    MySql 5.7 同时使用order by和limit时结果集不正确的问题 工作中写的一句sql根据日期排序后进行分页,结果缺失了一些数据,且出现了重复的数据. 在sql不断的调整尝试后发现,在同时 ...

最新文章

  1. java两个线程同时运行_java如何几乎同时结束两个线程
  2. oracle增量备份如何恢复,【Oracle】增量备份和全库备份怎么恢复数据库
  3. BAT面试题9:谈谈判别式模型和生成式模型?
  4. 狗窝里的小日子- 5 ...
  5. RedisCrawlSpider
  6. PyTorch 1.0 中文官方教程:torch.nn 到底是什么?
  7. 女孩去互联网大厂工作怎么样?
  8. 阿里云 MSE 微服务治理发布企业版
  9. 【图像检索】基于matlab GUI综合颜色和形状特征图像检索【含Matlab源码 395期】
  10. HP笔记本ProBook 445R G6刷BIOS历险记
  11. 数字电路基础知识(二) 复位设计-亚稳态的产生与影响
  12. Loadrunner脚本录制执行
  13. php页眉,如何在php中创建Word文档页眉/页脚
  14. 遗传算法的理解及例子解释
  15. Zeromq 学习笔记1
  16. Log4j简单xml配置
  17. 2021计算机专业课考研大纲,2021年计算机专业考研大纲原文
  18. Neo4j图数据库 批量写入与查询
  19. 1.3 一摞烙饼的排序
  20. 小鸡农场种植小游戏开发

热门文章

  1. QQ音乐爬取(python实现)
  2. ubuntu改变@后面的主机名
  3. PyTorch中MaxPool的ceil_mode属性
  4. akka框架——异步非阻塞高并发处理框架
  5. React-Native Navigator 过渡动画卡顿的解决方案
  6. RabbitMQ —— 延迟队列
  7. DIV+CSS笔记(一)
  8. UA MATH567 高维统计 专题0 为什么需要高维统计理论?——高维统计理论的常用假设
  9. UA MATH564 概率论VI 数理统计基础3 卡方分布上
  10. 达梦数据库的基本使用