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

C#使用BouncyCastle解密OpenSSL AES-128-CTR密文乱码问题

问题原因

解密得到乱码是两端加密配置不匹配导致的,共两处核心错误:

  • 密钥长度不匹配:使用的算法是AES-128-CTR,要求密钥长度严格为16字节。传入的key字符串F5UgsDQddWGdgjddJtNgg6xE3V9uwaCR经UTF8编码后为32字节,PHP OpenSSL扩展遇到密钥长度超过算法要求时,会静默截断前16字节作为实际加密密钥;但C#代码直接传入了完整32字节密钥,相当于使用AES-256参数解密,密钥完全不匹配。
  • 填充模式错误:CTR属于流密码工作模式,不需要任何填充。C#代码中指定的PKCS7PADDING是CBC/ECB等块密码模式使用的填充规则,CTR模式下使用会导致解密逻辑错误。

注:现有代码中IV长度16字节、密文base64解码的逻辑是正确的,无需修改。

修复方案

方案1:保持PHP代码不变,修正C#解密逻辑

做两处改动即可:

  1. 取密钥字符串前16个字符转字节数组,和PHP侧的截断逻辑对齐
  2. 将BouncyCastle加密算法的填充规则改为NoPadding

修正后的C#代码如下:

public string Decrypt(string toDecrypt, string keyStr, string ivStr)
{
    byte[] inputBytes = Convert.FromBase64String(toDecrypt);
    // 对齐PHP侧AES-128的密钥截断逻辑,取前16字符转字节
    byte[] keyBytes = Encoding.UTF8.GetBytes(keyStr.Substring(0, 16));
    byte[] iv = Encoding.UTF8.GetBytes(ivStr);
    // CTR为流模式,无需填充
    IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");
    cipher.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", keyBytes), iv));
    byte[] decryptedBytes = cipher.DoFinal(inputBytes);
    return Encoding.UTF8.GetString(decryptedBytes);
}

调用后可得到正确明文:The quick brown fox jumps over the lazy dog

方案2:保留32字节密钥,修正PHP代码

如果本意是使用32字节密钥做AES-256加密,只需要将PHP侧的加密算法改为AES-256-CTR,C#侧只需要把填充规则改为NoPadding、传入完整32字节密钥即可,无需截断。

补充说明:PHP openssl_encrypt在options参数为0时默认返回base64格式密文,现有C#代码的base64解码逻辑是正确的;如果PHP侧加了OPENSSL_RAW_DATA参数,才需要直接传入原始字节密文,不需要做base64转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:27:19