mbedtls加密数据无法通过Bouncy Castle正常解密问题排查
问题分析与解决方案
核心错误点
你的单片机加密代码存在两个关键错误,直接导致了Windows端解密异常:
IV生成时长度参数错误
mbedtls_ctr_drbg_random的第三个参数使用strlen((char*)iv)是完全错误的:iv是未初始化的局部数组,初始内容为栈内存垃圾值strlen会在遇到第一个\0字节时停止计算,导致只有前N个字节被随机填充,剩余字节为不可控的垃圾值- 正确做法是直接指定IV的固定长度16字节(AES-CBC要求IV长度等于块大小):
mbedtls_ctr_drbg_random( &DRBG_Context, iv, 16 );
IV返回时复制不完整
*IniVec = *InitializationVector;仅复制了IV的第一个字节,若IniVec用于返回完整16字节IV给调用方,必须用memcpy复制整个数组:memcpy(IniVec, InitializationVector, 16);
现象解释
你观察到"第一个块解密异常、第二个块正常"的现象,完全符合初始IV错误的特征:
- CBC模式中,第二个明文块的解密依赖第一个密文块作为临时IV,与初始IV无关,因此只要密钥正确,第二个块就能正常解密
- 第一个明文块的解密完全依赖初始IV,若IV包含垃圾字节,必然导致解密结果错误
- 单片机端解密正常是因为它使用了加密时实际生成的(含垃圾字节的)IV,与加密过程的IV完全匹配
Bouncy Castle代码补充优化
确保解密时使用无填充模式,你明确说明数据长度是16字节的整数倍,无需填充。Bouncy Castle在FIPS模式下默认可能使用PKCS7填充,需显式指定无填充:
IBlockCipherBuilder<IParameters<Algorithm>> decryptBuilder = provider.CreateBlockDecryptorBuilder( FipsAes.Cbc.WithIV(iv).WithPadding(FipsAes.NoPadding) );
修复步骤
- 修正单片机端IV生成和返回的代码错误
- 重新生成加密数据,确保IV为完整16字节随机值
- 验证Windows端使用的IV与加密时的初始IV完全一致
- 确认Bouncy Castle解密代码使用无填充模式
内容的提问来源于stack exchange,提问作者russ
相关产品推荐
相关产品推荐

