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

React Native CryptoJS加密文本在C#解密报错:填充无效求排查

解决React Native CryptoJS AES加密与C#解密的Padding无效问题

你的C#解密代码和CryptoJS的默认加密逻辑存在多处不匹配,导致解密时触发"Padding is invalid"错误,具体问题及修正方案如下:

关键不匹配点

  • 加密模式:CryptoJS.AES默认使用CBC模式,你的代码错误使用了ECB模式。
  • 密钥/IV生成逻辑:CryptoJS直接传入字符串密钥时,采用OpenSSL的EVP_BytesToKey算法生成密钥和IV,而非你代码中的PBKDF2。
  • 密文格式处理:CryptoJS生成的Base64密文包含Salted__前缀+随机盐+实际密文,你的代码未提取盐和有效密文,直接解密整个字节数组。

修正后的C#解密代码

1. 实现CryptoJS兼容的EVP_BytesToKey算法

private static (byte[] Key, byte[] IV) EVP_BytesToKey(string password, byte[] salt, int keySize, int ivSize)
{
    List<byte> key = new List<byte>();
    List<byte> iv = new List<byte>();
    byte[] currentHash = Array.Empty<byte>();
    byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
    
    while (key.Count < keySize || iv.Count < ivSize)
    {
        using (MD5 md5 = MD5.Create())
        {
            byte[] input = new byte[currentHash.Length + passwordBytes.Length + salt.Length];
            Buffer.BlockCopy(currentHash, 0, input, 0, currentHash.Length);
            Buffer.BlockCopy(passwordBytes, 0, input, currentHash.Length, passwordBytes.Length);
            Buffer.BlockCopy(salt, 0, input, currentHash.Length + passwordBytes.Length, salt.Length);
            
            currentHash = md5.ComputeHash(input);
            key.AddRange(currentHash);
            if (iv.Count < ivSize)
            {
                iv.AddRange(currentHash);
            }
        }
    }
    
    return (key.Take(keySize).ToArray(), iv.Take(ivSize).ToArray());
}

2. 修正解密方法

public string Decrypt(string encryptedText, string secretKey)
{
    byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
    
    // 校验并解析CryptoJS密文格式:前8字节为"Salted__",接下来8字节是盐,剩余为实际密文
    if (encryptedBytes.Length < 16 || !Encoding.ASCII.GetString(encryptedBytes, 0, 8).Equals("Salted__"))
    {
        throw new ArgumentException("无效的CryptoJS加密格式");
    }
    
    byte[] salt = encryptedBytes.Skip(8).Take(8).ToArray();
    byte[] actualCiphertext = encryptedBytes.Skip(16).ToArray();
    
    using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
    {
        aes.KeySize = 256;
        aes.Mode = CipherMode.CBC; // 匹配CryptoJS默认模式
        aes.Padding = PaddingMode.PKCS7;
        
        // 生成兼容的密钥和IV
        var (key, iv) = EVP_BytesToKey(secretKey, salt, aes.KeySize / 8, aes.BlockSize / 8);
        aes.Key = key;
        aes.IV = iv;
        
        // 执行解密
        using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
        using (MemoryStream msDecrypt = new MemoryStream(actualCiphertext))
        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
        {
            return srDecrypt.ReadToEnd();
        }
    }
}

注意事项

  • 调用Decrypt时,传入的secretKey必须和React Native中CryptoJS使用的密钥完全一致(你之前代码里硬编码了key = "my secret key",建议改为使用参数secretKey)。
  • CryptoJS加密时如果手动指定了盐、模式或IV,C#代码需要同步对应参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:55:02