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

PHP转C#:Rijndael-256加密逻辑输出不一致问题排查

PHP转C#的Rijndael-256加密输出不一致问题排查

我帮你梳理下代码里和PHP原始逻辑不一致的关键地方,这些就是导致输出不同的核心原因:

1. 参数数组的JSON结构完全不符

PHP里的$arParams是关联键值对数组,序列化后是类似{"success_url":"xxx", "fail_url":"xxx"}的JSON对象;但你写的C#代码用的是匿名对象数组,序列化后会变成["xxx", "xxx", "xxx"]的JSON数组,这一步的输入就和PHP完全不一样,后续加密结果肯定不同。

正确的C#参数声明应该用键值对结构,比如:

var arParams = new Dictionary<string, string>
{
    {"success_url", "http://google.com/new_success_url"},
    {"fail_url", "http://google.com/new_fail_url"},
    {"status_url", "http://google.com/new_status_url"},
};

2. 密钥处理逻辑完全偏离PHP

PHP的mcrypt_encrypt是直接使用传入的原始$key作为加密密钥,但你的C#代码对密钥做了MD5哈希 + Rfc2898密钥推导的额外处理,这是完全多余的操作,直接导致加密用的密钥和PHP不一致。

你需要直接使用原始的$key对应的字节数组(注意编码一致性,PHP默认用UTF-8的话,C#也要用Encoding.UTF8.GetBytes(key))。

3. Rijndael加密配置的细节差异

填充模式不符

PHP的mcrypt_encrypt在ECB模式下默认使用零填充(Zero Padding),但你的C#代码设置的是PaddingMode.PKCS7,这会导致加密时的填充逻辑不同,输出字节数组自然不一样。

ECB模式不需要IV

ECB模式本身不需要初始化向量(IV),PHP里调用mcrypt_encrypt时ECB模式会忽略IV参数,但你的C#代码依然生成并传入了IV,虽然ECB模式实际不会用,但最好明确去掉IV的设置,避免潜在问题。

加密时的字节转换方式

你用StreamWriter来写入明文,可能会引入编码差异(比如默认BOM问题),更稳妥的方式是直接把JSON字符串转成UTF-8字节数组后再加密。

修正后的完整C#代码示例

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using Newtonsoft.Json;

class Program
{
    static void Main(string[] args)
    {
        // 替换成你的实际key
        string key = "your_php_key_here";
        // 1. 构造正确的键值对参数
        var arParams = new Dictionary<string, string>
        {
            {"success_url", "http://google.com/new_success_url"},
            {"fail_url", "http://google.com/new_fail_url"},
            {"status_url", "http://google.com/new_status_url"},
        };

        // 2. 序列化为JSON字符串(和PHP json_encode一致)
        string jsonEncoded = JsonConvert.SerializeObject(arParams);
        byte[] plainBytes = Encoding.UTF8.GetBytes(jsonEncoded);

        // 3. Rijndael-256 ECB加密配置
        using (var rijndael = new RijndaelManaged())
        {
            rijndael.Mode = CipherMode.ECB;
            rijndael.BlockSize = 256; // 对应PHP的MCRYPT_RIJNDAEL_256
            rijndael.Padding = PaddingMode.Zeros; // 和PHP默认填充一致
            rijndael.Key = Encoding.UTF8.GetBytes(key);

            // 创建加密器并执行加密
            ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, null);
            byte[] encryptedBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);

            // 4. Base64编码 + URL编码
            string base64Str = Convert.ToBase64String(encryptedBytes);
            string m_params = HttpUtility.UrlEncode(base64Str, Encoding.UTF8);

            Console.WriteLine("最终m_params: " + m_params);
        }
    }
}

额外验证建议

你可以分步对比每一步的输出:

  • 先对比PHP和C#的JSON序列化结果,确保完全一致
  • 再对比加密前的明文字节数组,确保编码一致
  • 最后对比加密后的字节数组、Base64字符串,逐步排查问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:29:54