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

C#中AES CBC 128 PKCS1填充解密无原生支持该如何实现?

AES-128-CBC PKCS1填充解密解决方案

前置确认

首先说明:PKCS#1填充原本是为RSA非对称加密设计的标准,对称加密场景默认通用的是PKCS#7填充。如果确认加密侧确实是AES-128-CBC搭配PKCS#1填充规则,可按以下两种方案处理,无需担心C#原生类库不支持的问题。

方案1:基于原生AES类自行实现填充处理

C#自带的AesCryptoServiceProvider只需要关闭自动填充,解密完成后自行处理PKCS#1填充的校验和移除即可,无需引入额外依赖。

实现步骤:

  • 初始化AesCryptoServiceProvider实例,正常配置128位密钥、CBC模式、IV参数,显式将Padding属性设置为PaddingMode.None
  • 调用原生解密接口得到未处理填充的原始字节数组
  • 对解密后的字节数组执行PKCS#1填充校验和内容提取,PKCS#1 v1.5填充结构规则如下:

解密后的数据首字节为0x02,后跟N个非零随机字节,之后为1个0x00分隔符,分隔符之后的内容为真实明文。

  • 填充移除参考代码:
using System;
using System.Security.Cryptography;

public static byte[] RemovePkcs1Padding(byte[] decryptedRawData)
{
    if (decryptedRawData == null || decryptedRawData.Length < 3)
        throw new ArgumentException("解密数据长度非法");
    
    if (decryptedRawData[0] != 0x02)
        throw new CryptographicException("不符合PKCS#1 v1.5填充规则");
    
    int separatorPos = -1;
    for (int i = 1; i < decryptedRawData.Length; i++)
    {
        if (decryptedRawData[i] == 0x00)
        {
            separatorPos = i;
            break;
        }
    }

    if (separatorPos == -1 || separatorPos == decryptedRawData.Length - 1)
        throw new CryptographicException("填充分隔符不存在,数据已损坏");
    
    return decryptedRawData.AsSpan(separatorPos + 1).ToArray();
}

方案2:使用BouncyCastle第三方加密库

如果不想自行实现填充校验逻辑,可以使用业界通用的BouncyCastle加密库,它原生支持PKCS#1填充配置,无需手动处理填充逻辑。

操作步骤:

  • 通过NuGet安装Portable.BouncyCastle包
  • 调用BouncyCastle封装的AES解密接口,直接指定填充规则为PKCS#1即可完成解密

注意事项

  • 优先校验加密侧的填充规则,很多场景会出现PKCS#7和PKCS#1的命名混淆,如果填充校验一直失败,可以先输出解密后的原始字节数组确认填充结构,再调整处理逻辑
  • 自行实现填充处理时不要跳过填充合法性校验,避免恶意构造的密文引发安全问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:21:02