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
相关产品推荐
相关产品推荐

