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

AES解密报错Invalid AES key length: xx bytes与Given final block not properly padded的解决方法 最近和其它系统联调接口,用到了Java的AES加解密。由其它系统AES加密,本人的系统获取到加密报文后,AES解密,获取到内容。本来是比较简单的,可是其它系统只提供了秘钥,没有提供解密方法,解密方法需要我们自己写……还好最后都解决了,在此记录下。 阅读详情
这两天一直在为文件加密解密时,由于关闭数据转换链接流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;
}
理解AES加密解密的使用方法 很多人对于AES加密并不是很了解,导致互相之间进行加密解密困难。 本文用简单的方式来介绍AES在使用上需要的知识,而不涉及内部算法。最后给出例子来帮助理解AES加密解密的使用方法。 阅读详情

相关推荐

Java中使用Hutool进行AES加密解密详解

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式编程的简洁性。Hutool中的工具方法来自于每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当。Hutool作为一款实用的Java工具类库,为开发者提供了简洁易用的AES加密解密API。

My_wife_QBL的博客 9449

C#高级--加密解密详解

https://blog.youkuaiyun.com/liyou123456789/article/details/120609269

xwnxwn的专栏 1471

C#高级编程:加密解密

C# 高级编程中的加密解密技术是保障数据安全的重要手段。通过对称加密、非对称加密和哈希算法的合理运用,以及在各种实际场景中的灵活部署,开发者能够有效保护数据的机密性、完整性和真实性。随着技术的不断发展,新的加密算法和安全标准也在不断涌现,开发者需要持续关注并学习,以应对日益复杂的安全挑战,为用户和企业构建更加安全可靠的应用程序。

hy_4377的博客 1452

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

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

shihuaicheng的专栏 4387

Python实现AES加密解密

报错: TypeError: decrypt() cannot be called after encrypt() 原因: cryptor不能写在主函数中同时给加密函数与解密函数使用,尽管加密解密都是用: cryptor = AES.new(key, mode, iv), 但若将其定义在main并分别传给加密解密同时使用时,会报错。 解决: 在加密与解密方法分别写cryptor = AES.new(key, mode, iv) 报错: ValueError: Incorrect IV l

s_kangkang_A的博客 6020

【Kotlin】加密解密2:DES、AES加密和解密

文章目录AES加密解密DES和AES密钥长度 AES加密解密 object AESCrypt{ //加密 fun encrypt(input:String,password:String): String { //创建cipher对象 val cipher = Cipher.getInstance("AES") //初始化:加密/解密...

Errol's Blog 2320

解决解密时出现"要解密的数据的长度无效" 或 "填充无效无法被移除" 的错误

1、首先排除数据库中读取加密后的字段是否被强制截断。 2、AES加密后的byte[]首先应用base64(Convert.ToBase64String)编码一次,若直接用utf8的话会报上述错误,若用unicode编码的话会解密成乱码,原因是加密后的byte数组用其他编码方式编码的话会丢失字符。 3、base编码后的字符串恢复为数组可用Convert.FromBase64Strin...

a5101288的博客 4822

洛谷P5707 【深基2.例12】上学迟到(c语言)

第一篇题解 题目描述 yyy 的学校要求早上 8 点前到达。学校到 yyy 的家一共有 s(s\le 10000)s(s≤10000) 米,而 yyy 可以以 v(v<10000)v(v<10000) 米每分钟的速度匀速走到学校。此外在上学路上它还要额外花 10 分钟时间进行垃圾分类。请问为了避免迟到 yyy 最晚什么时候出门?输出 HH:MM 的时间格式,不足两位时补零。由于路途遥远, yyy 可能不得不提前一天出发,不过不可能提前超过一天。 输入格式 两个正整数 s,v,意思已经在题目中给定

cc_love_program的博客 1万+

AES解密中FlushFinalBlock遇到的错误 解决方案 和疑问

我想using System.Security.Cryptography;实现AES的加密解密功能,加密可以正常进行解密时红色地方的语句会出现异常。  如果算法用的DES就没这个问题,请问这个异常怎么解决,微软官方上都没解决方案,国外一些提问网站也没解决。不知道谁能告诉我怎么做  //AES加密        public static string EnAES(strin

whwhzzz的专栏 4171

精益六西格玛Python数字化应用开发-Day18 应用场景:家电企业生产效率优化

本文将重点介绍专门针对精益六西格玛黑带使用场景的 Python 库,这些库功能侧重于数据分析和流程优化,特别适用于 DMAIC 方法论和看板管理。考虑到读者具备中高级Python 使用经验,我们将深入探讨各库的高级功能和实际应用应用场景。 某家电企业生产线自动化程度高,数据量巨大,希望通过精益管理提升生产效率。企业借助 Python 脚本,打通各类数据源(MES、ERP、设备日志),自动归集生产数据,分析各工序的生产节拍、设备停机、效率损失,快速定位瓶颈环节

m0_56592100的博客 905

【SWPUCTF 2021 新生赛】hardrce

对每个字符的ASCII值进行按位取反操作(这种要进行自增马进行绕过。

XiaoHei的博客 460

sm4算法加密解密

一、基本知识 分组加密(英语:Block cipher),又称分块加密或块密码,是一种对称密钥算法。它将明文分成多个等长的模块(block),使用确定的算法和对称密钥对每组分别加密解密。 对称加密、加密算法主要可以分为两种,一个是非对称加密算法,另一个就是对称加密算法。对称加密简单来说就是有一个明文,通过一个密钥加密之后得到一个密文,这个密文可以通过相同的密要解密得出和原来相同的明文 二、sm...

bird_tp的博客 5万+

【论文精读】Latent Diffusion

Latent Diffusion

weixin_44934783的博客 4476

Python 实现高效的 SM4 大文件加密解密实战指南20241024

python 图片压缩 sm4

Narutolxy的博客 2752

英飞凌功率MOSFET SPICE 瞬态仿真不收敛问题解决(基于TINA)

英飞凌功率MOSFET SPICE仿真容易出现不收敛问题,这个对于IGBT和SIC的管子应该是一样的,在瞬态仿真分析中,出现如下图所示的报错,Convergence problem。spice是为线性电路设计的,例如运算放大器、线性电源等,不是专门仿真开关电路的。在瞬态仿真时,仿真器是要不断迭代求解的,开关快速的跳变,容易在迭代式出现不收敛的问题。,由于时间步长减少,会消耗更多的计算机内存,如果运行多次内存消耗过大,会报“Out of memory”.解决方法是:报错工程,重启软件,内存重新计算。

miaoxiaokeji的博客 2296

40、基于指令的GPU编程:OpenACC与OpenMP的深入解析

本文深入解析了两种基于指令的GPU编程模型——OpenACC和OpenMP。从编程复杂度、数据处理方式和性能表现等多个方面对两者进行了对比分析,并结合实际应用场景提供了选择建议。通过详细的代码示例和性能测试结果,帮助开发者更好地理解和应用这两种编程模型,以充分发挥GPU的并行计算能力。

q5r6s7的博客 134

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

tomcat中的加密程序需要换到iis中,用起了 C#中的 DESCryptoServiceProvider,上网找了些相关流程写了个类,感觉比java的程序精简。 但测试中发现异常,同一次测试中,加密,解密都正常。但把加密的base64字符串,再另外测试就出现“不正确的数据”的提示。 然后再上网对比了很多,没看到什么不对的地方。程序如下: using System; using Sy

counterm的专栏 1万+

【unity实战】使用unity的Navigation+LineRenderer实现一个3D人物寻路提前指示预测移动轨迹的效果,并可以适配不同的地形

本文介绍了在Unity中使用Navigation导航系统和LineRenderer实现3D人物寻路轨迹预测效果的方法。通过NavMesh.CalculatePath计算路径点,结合Physics.Raycast进行地面点投射,将路径点赋予LineRenderer渲染出移动轨迹。关键点包括:1)利用NavMesh.CalculatePath计算两点间可行走路径;2)通过射线检测获取地面点提高路径适配性;3)使用协程定期更新路径绘制。文章还提供了完整代码实现,并说明需要将地面图层设置为Ground并进行导航网格

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 458

RSA加密解密详解

RSA算法是非对称密码算法。非对称密码又称为公钥密码,意思为每对加密包含一个公钥(可能为他人所知)和一个私钥(可能不为所有人所知)。有效的安全需要保持私钥的私密性;公钥可以在不影响安全性的情况下公开分发。RSA 的安全性依赖于分解两个大素数乘积的实际困难,但相对较慢,可以称为“分解问题”。已知:P = 11,q = 29,e = 3φ(n) = (p-1)(q-1) = (11-1)*(29-1) = 2803d ≡ 1 mod 280 3d mod 280 = 1 d = 187n = 11 * 29 =

weixin_43211186的博客 2万+

ASProxy64.dll导致jetbrains家的IDE都无法打开。

摘要:在Windows11系统中,JetBrains IDE无法启动,报错指向ASProxy64.dll文件。该第三方DLL被注入到JVM原生层,导致内存访问冲突(错误代码0xc0000005)。经排查发现此文件来自Astrill软件。解决方案为卸载Astrill后重启电脑,问题得以解决。该案例表明第三方DLL注入可能影响IDE正常运行,卸载相关软件是最直接的解决方法。(149字)

猿小白的博客 936

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C语言基本加密解密

基本加密解密 对于位运算来说,由于两次异或运算可以将值还原这个特性,所以经常使用异或进行加密解密运算,如下: 0 ^ 0 = 0 0 ^ 0 = 0 1 ^ 0 = 1 1 ^ 0 = 1 0 ^ 1 = 1 1 ^ 1 = 0 1 ^ 1 = 0 0 ^ 1 = 1 根据上面结果无论两个char还是两个int或者别的类型,甚至两个不同类型、不同长度的数据两次异或后都可以还原,这就为加密解密提供了理论保障。密码可以是一个数值,只要将需要加密的内容的每个字节与这个数值异或即可,但采用字符串作为密码更

jaj2003的博客 7608

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

解决SM4加密解密过程XML文件中出现的乱码问题

数据信息通过XML文件在不同网络中传递时,为了保证数据安全往往需要通过SM4、BASE64等算法对传输的内容进行加密,接收方在接收到加密XML文件后再进行解密。但是最近在使用中出现了一个问题:通过SM4算法解密的XML文件,偶尔会在文件末尾出现乱码。本文介绍了如何解决出现的这个问题。

qq_46119575的博客 4276

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【Java】MD5字符串的加密解密

至于为什么要给字符串加密解密,各种加密解密的方式优缺点对比等等,本文都不会讲,弄点实用的代码,给需要应急的朋友应急 废话不多说,看代码了: import java.security.Key; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.securi...

少年休闲海 5605

android rsa分段加密超出长度,分段加解密解决RSA“不正确的长度”的异常

RSA 是常用的非对称加密算法。最近使用时却出现了“不正确的长度”的异常,研究发现是由于待加密的数据超长所致。RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行。 RSA加密对明文的长度是有限制的,如果加密数据过大会抛出如下异常:Exception in thread “main” javax.crypto.IllegalBlockSizeEx...

weixin_29839415的博客 1525

Aes 加密解密 java加密解密

使用AES加密解密代码详解 首先,如果是使用nodejs + vue 写的前端, 那么你需要npm 加载一个js文件 npm i crypto-js --save --save-exact npm install crypto-js java代码加密解密类 package com.telling.util.crypto; import javax.crypto.Cipher; ...

后知后觉 1208
上一篇: 将数字金额转换为中文大写金额(在网上找的)
下一篇: .NET消息传送过程中的涉及到加密解密示例图
PPLUNCLE
博客等级 码龄24年 3粉丝 51原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值