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

求助:将CryptoJS.AES.decrypt的JavaScript代码转为C#实现

解决CryptoJS AES解密的C#实现问题

你的JavaScript代码依赖CryptoJS的默认AES解密逻辑,它处理的是OpenSSL格式的加密数据(开头U2FsdGVkX1对应Base64解码后的Salted__标识)。以下是完全匹配该逻辑的C#实现:

核心逻辑说明

CryptoJS使用密码而非直接密钥时,会执行以下步骤:

  1. 从密文开头提取8字节盐值(前8字节为固定标识Salted__,后续8字节是实际盐)
  2. 通过PBKDF2算法,以密码、盐为输入,生成32字节AES密钥和16字节IV(默认迭代次数1000,哈希算法SHA-1)
  3. 使用AES-CBC模式、PKCS7填充解密剩余密文

完整C#代码

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class AesDecryptor
{
    public static string Decrypt(string ciphertextBase64, string password)
    {
        // 解码Base64密文
        byte[] ciphertextBytes = Convert.FromBase64String(ciphertextBase64);
        
        // 提取盐和实际加密数据:前8字节是"Salted__",接下来8字节是盐,剩余是加密内容
        byte[] salt = new byte[8];
        Array.Copy(ciphertextBytes, 8, salt, 0, 8);
        byte[] encryptedData = new byte[ciphertextBytes.Length - 16];
        Array.Copy(ciphertextBytes, 16, encryptedData, 0, encryptedData.Length);
        
        // 用PBKDF2生成密钥和IV
        byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
        byte[] keyAndIv = GenerateKeyAndIv(passwordBytes, salt);
        byte[] key = new byte[32];
        byte[] iv = new byte[16];
        Array.Copy(keyAndIv, 0, key, 0, 32);
        Array.Copy(keyAndIv, 32, iv, 0, 16);
        
        // AES-CBC解密
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
            
            using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
            using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            using (StreamReader srDecrypt = new StreamReader(csDecrypt))
            {
                return srDecrypt.ReadToEnd();
            }
        }
    }
    
    private static byte[] GenerateKeyAndIv(byte[] password, byte[] salt)
    {
        // 匹配CryptoJS默认PBKDF2参数:1000次迭代,SHA-1哈希,生成48字节(32位密钥+16位IV)
        using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt, 1000, HashAlgorithmName.SHA1))
        {
            return pbkdf2.GetBytes(48);
        }
    }

    // 测试示例
    public static void Main()
    {
        string ciphertext = "U2FsdGVkX1+pmKonC+E+MGs9BltH/axDE3IRYIV+vHF0yuteP4JAzuQ/CmmSgY2xkqeAhl02bIL5cJhsE1NOsc79ENadltxt2QEBymquSnbUsuhtxHptgGUXV0XuSPPQAt4/Rk2bDaR7qJw2LJKh4U1/pqeJUlqP2qLdtBTLs7E+W2TVh0/yMAVyuGUctEtx41qOClFzyfPxNydtSO6vzQ+3OOrI4Ov7ZgX07OJIF5sAq+m3pJQspL93UHbKS1w7a4dJUn2s+7JRYASkD9IBsheXI//SiE3yJv3c/dOs3VFDl4ok+m0MkgMwHQ0ELySUx1/UVTY6lefenO2RgASE52ATwIyKy7rdf4GKnrYpU7rdMZwcu1enI8Jpz5Ri3pFioyJSiPPDVKIecDQJ+UsQpsszWA6mQb3YMRhIxJrdcjSGEIHPGTHFEYgVpSO9y4EeGKLvX5oJ0tQDhO+QW1LQszcojRsgFuyFkdAsjNVzRNK3K4qE6Ua8j6t/kyE9i/MW7DQ0nT3d3CozLGS68PdEI34kljArY6Hmrgkt4InvBKdMvfffogKE3NtwBhf/3nK5";
        string password = "F2Gs3zjSjd3";
        string result = Decrypt(ciphertext, password);
        Console.WriteLine(result);
    }
}

关键注意事项

  • 必须严格解析OpenSSL格式的密文结构,不能直接解密整个Base64数据
  • 完全匹配CryptoJS的PBKDF2参数,否则生成的密钥/IV会不一致
  • AES模式和填充方式必须用CBC+PKCS7,这是CryptoJS的默认配置

内容的提问来源于stack exchange,提问作者Raúl Gavilanes Lara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:05:17