You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AES加密后伪装还原引发“Padding无效无法移除”错误排查

AES解密"Padding is invalid and cannot be removed"异常排查与解决

问题概述

在C#中使用Aes.Create()实现敏感FTP凭证加密存入SQLite的流程,基础加密解密逻辑运行正常。但添加三套字符串伪装/还原逻辑以隐藏数据库中存储的cipher、key、IV值后,解密时抛出System.Security.Cryptography.CryptographicException,错误提示为**"Padding is invalid and cannot be removed"**。

已尝试的无效方案

  • 替换为AesManaged类,问题未解决
  • 设置PaddingMode.None,触发数据长度无效错误
  • 设置PaddingMode.Zeros,解密结果出现乱码
  • 验证伪装还原后的字符串与原字符串一致,但解密仍报错

异常原因分析

表面上伪装还原后的字符串与原字符串一致,但实际大概率存在不可见字符差异或编码转换错误:

  1. 编码不一致:伪装/还原过程中混用不同字符编码(如UTF-8和UTF-16),导致字节流发生不可逆变化,AES解密时无法识别合法填充位
  2. 隐式转换篡改:使用Encoding.Default进行字节数组与字符串转换时,受系统默认编码影响,还原后的字节数组与加密时的原始字节数组不匹配
  3. 填充位意外修改:伪装逻辑的字符级操作无意中篡改了加密字节流末尾的填充位,导致AES解密时无法通过填充验证

解决步骤

1. 隔离验证核心解密流程

暂时移除所有伪装/还原逻辑,直接将加密后的原始字节数组(或其Base64编码)存入数据库再解密。若此时流程正常,即可确认问题出在伪装/还原环节。

2. 对比伪装前后的字节数组

不要仅对比字符串,直接校验字节数组的一致性:

// 示例:逐字节对比原始与还原后的字节数组
bool isBytesMatch = originalEncryptedBytes.SequenceEqual(restoredEncryptedBytes);

若结果为false,逐环节排查伪装逻辑中篡改字节流的位置。

3. 统一字符编码规范

在所有字节数组与字符串转换环节,强制使用UTF-8编码(避免依赖系统默认编码),优先用Base64处理加密后数据:

// 加密后字节转安全字符串(无不可见字符)
string safeEncryptedStr = Convert.ToBase64String(encryptedBytes);
// 还原时字符串转字节数组
byte[] restoredBytes = Convert.FromBase64String(safeEncryptedStr);

若必须使用自定义伪装,建议直接基于字节数组操作,避免字符编码干扰。

4. 校验AES参数一致性

确保加密与解密时的AES参数完全一致:

  • 密钥(Key)长度必须符合AES标准(128/192/256位)
  • 初始向量(IV)必须与加密时完全相同
  • 加密模式(如CBC)和填充模式(如PKCS7)必须前后统一

5. 调整伪装逻辑实现

放弃直接对加密字符串的字符级伪装,改用更安全的流程:

  1. 加密后将字节数组转为Base64字符串(避免不可见字符问题)
  2. 对Base64字符串执行可逆伪装操作(如固定规则的字符替换、位移)
  3. 还原时先恢复为原始Base64字符串,再转为字节数组解密

核心需求适配建议

针对你的WinForms/SQLite应用(用于简化Let's Encrypt证书申请、保护FTP凭证):

  • 无需单独加密存储cipher、IV值,IV可明文存储,仅需重点保护密钥
  • 密钥不要硬编码在程序中,可通过用户输入、Windows凭据管理器或硬件加密模块获取

内容的提问来源于stack exchange,提问作者Art Hansen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 03:15:46