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

Angular加密数据后,如何在C#(.NET)服务端完成解密?

Angular AES加密后C#/.NET解密问题

我有Angular端的数据加密代码,但不知道怎么在C#/.NET服务端解密。

Angular加密代码

public static getEncryptedInfo(dataString): string {
    let password = environment.encryptionKey;
    var text = dataString.toString(CryptoJS.enc.Utf8)
    var encrypted = CryptoJS.AES.encrypt(text, password).toString();
    const encodedComponent = encodeURIComponent(encrypted).toString();
    return encodedComponent;
}

使用的encryptionKey为12345,加密后的示例值:

U2FsdGVkX19klqZyBO7JyNzfxCBxAizFPkVYX%2Bb%2BUNs%2FVGEcr%2Fcxz3JmQcEgiojQ

我把加密值传到服务端后,写了下面的C#解密代码,但运行报错,请问哪里错了?

尝试的C#解密代码

public static string Decrypt(string plainText)
{
    RijndaelManaged aes = new RijndaelManaged();
    string decodeString = System.Web.HttpUtility.UrlDecode(plainText);
    var base64Decode = Encoding.UTF8.GetString(Convert.FromBase64String(decodeString));

    // var inputArray = Convert.FromBase64String(decodeString);
    ICryptoTransform AESDecrypt = aes.CreateDecryptor();

    var de = AESDecrypt.TransformFinalBlock(base64Decode, 0, base64Decode.Length);
    return encoding.GetString(de);
}

public static string DecryptText(string EncryptedText)
{
    if (string.IsNullOrEmpty(EncryptedText))
    {
        return "";
    }
    else
    {
        RijndaelManaged aes = new RijndaelManaged();
        string decodeString = System.Web.HttpUtility.UrlDecode(EncryptedText);
        var base64Decode = Encoding.UTF8.GetString(Convert.FromBase64String(decodeString));
        Byte[] outputBytes = StringToByteArray(base64Decode);
        var bytesToDecrypt = Convert.FromBase64String(EncryptedText);
        CryptoJS.AES.decrypt(encodedBytes, Secretkey).toString(CryptoJS.enc.Utf8)
        var actualText = Encoding.UTF8.GetString(base64Decode);

        var  de = base64Decode.Substring(0, base64Decode.Length - DecryptionKey.Length);

        return de;
    }
}

问题分析

你的C#代码存在多个关键错误:

  • 未处理CryptoJS的AES格式:CryptoJS的AES.encrypt默认生成OpenSSL兼容格式(前缀Salted__+8字节盐值+密文),你直接对Base64解码后的字符串做处理,完全没解析这个格式。
  • 密钥生成逻辑缺失:CryptoJS用密码加密时,会通过EVP_BytesToKey算法从密码和盐值生成AES密钥和IV,你的代码没实现这个逻辑,用默认Rijndael参数必然失败。
  • 二进制数据处理错误:把Base64解码后的字节转成UTF8字符串再处理,会破坏原始二进制数据,导致解密失败。
  • 代码逻辑混乱:DecryptText中出现了CryptoJS的JS代码(C#无法运行),还有未定义的变量(如encodedBytes、Secretkey)。

正确的C#解密实现

下面是适配CryptoJS默认AES加密逻辑的C#代码:

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

public static class AesCryptoJsDecryptor
{
    public static string Decrypt(string encryptedText, string password)
    {
        // 1. URL解码加密字符串
        string decodedText = System.Web.HttpUtility.UrlDecode(encryptedText);
        // 2. Base64解码为字节数组
        byte[] encryptedBytes = Convert.FromBase64String(decodedText);

        // 验证CryptoJS格式:前8字节必须是"Salted__"
        if (encryptedBytes.Length < 16 || !Encoding.ASCII.GetString(encryptedBytes, 0, 8).Equals("Salted__"))
        {
            throw new ArgumentException("无效的CryptoJS AES加密数据");
        }

        // 提取盐值和密文
        byte[] salt = new byte[8];
        Array.Copy(encryptedBytes, 8, salt, 0, 8);
        byte[] ciphertext = new byte[encryptedBytes.Length - 16];
        Array.Copy(encryptedBytes, 16, ciphertext, 0, ciphertext.Length);

        // 通过EVP_BytesToKey生成密钥和IV(CryptoJS默认算法)
        (byte[] key, byte[] iv) = DeriveKeyAndIv(password, salt);

        // 执行解密
        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(ciphertext))
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            using (StreamReader srDecrypt = new StreamReader(csDecrypt))
            {
                return srDecrypt.ReadToEnd();
            }
        }
    }

    // 实现CryptoJS使用的EVP_BytesToKey密钥派生算法
    private static (byte[] key, byte[] iv) DeriveKeyAndIv(string password, byte[] salt)
    {
        byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
        List<byte> keyIvBuffer = new List<byte>();
        byte[] currentHash = Array.Empty<byte>();

        using (MD5 md5 = MD5.Create())
        {
            // 循环生成足够的字节(AES-256需要32字节密钥+16字节IV)
            while (keyIvBuffer.Count < 32 + 16)
            {
                byte[] inputBytes = new byte[currentHash.Length + passwordBytes.Length + salt.Length];
                currentHash.CopyTo(inputBytes, 0);
                passwordBytes.CopyTo(inputBytes, currentHash.Length);
                salt.CopyTo(inputBytes, currentHash.Length + passwordBytes.Length);

                currentHash = md5.ComputeHash(inputBytes);
                keyIvBuffer.AddRange(currentHash);
            }
        }

        byte[] key = keyIvBuffer.GetRange(0, 32).ToArray();
        byte[] iv = keyIvBuffer.GetRange(32, 16).ToArray();
        return (key, iv);
    }
}

使用示例

string encryptedValue = "U2FsdGVkX19klqZyBO7JyNzfxCBxAizFPkVYX%2Bb%2BUNs%2FVGEcr%2Fcxz3JmQcEgiojQ";
string decryptedText = AesCryptoJsDecryptor.Decrypt(encryptedValue, "12345");
Console.WriteLine(decryptedText); // 输出原始明文

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:05:24