简体   繁体   English

如何在 Angular 11 中使用 CryptoJS 来获得相同的解密字符串,如 C# Rfc2898DeriveBytes

[英]How to use CryptoJS in Angular 11 to get same decrypted string like C# Rfc2898DeriveBytes

I need to convert C# AES encryption/decryption to its equivalent in Angular 11, so it could give the same result.我需要将 C# AES加密/解密转换为 Angular 11 中的等效项,因此它可以给出相同的结果。 I use crypto-js as AES library.我使用crypto-js作为 AES 库。 I have already done encryption (both C# and Angular), but I can not deal with decryption on Angular side.我已经完成了加密(C# 和 Angular),但我无法处理 Angular 端的解密。 I quess it may just slightly differ from encryption.我怀疑它可能与加密略有不同。 Can you help me with it?你能帮我吗? Here are code samples:以下是代码示例:

C# encryption C# 加密

private const int KeyLength = 2048;
private const int KeyCB = 32;
private const int IvCB = 16;
private const CryptoStreamMode Mode = CryptoStreamMode.Write;
private const PaddingMode Padding = PaddingMode.PKCS7;

private readonly byte[] Salt = new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };

public string Encrypt(string origin, string key)
{
    try
    {
        byte[] clearBytes = Encoding.Unicode.GetBytes(origin);
        using (var encryptor = Aes.Create())
        {
            encryptor.Padding = Padding;
            var pdb = new Rfc2898DeriveBytes(key, Salt);
            encryptor.Key = pdb.GetBytes(KeyCB);
            encryptor.IV = pdb.GetBytes(IvCB);
            using var ms = new MemoryStream();
            using (var cs = new CryptoStream(ms, encryptor.CreateEncryptor(), Mode))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
                cs.Close();
            }
            origin = Convert.ToBase64String(ms.ToArray());
        }
        return origin;
    }
    catch (Exception)
    {
        throw;
    }
}

Angular encryption Angular加密

private readonly SALT = CryptoJS.enc.Base64.parse('SXZhbiBNZWR2ZWRldg==');
private readonly ITERATIONS = 1000; 

Encrypt(origin: string, key: string): string{
  try {
    let keyWordArray = CryptoJS.enc.Utf8.parse(key);
    let originWordArray = CryptoJS.enc.Utf16LE.parse(origin);
    let keyAndIv = CryptoJS.PBKDF2(keyWordArray, this.SALT, { 
      keySize: 256/32 + 128/32, 
      iterations: this.ITERATIONS, 
      hasher: CryptoJS.algo.SHA1 
    });
    let hexKeyAndIv = CryptoJS.enc.Hex.stringify(keyAndIv);
    let hexKey = CryptoJS.enc.Hex.parse(hexKeyAndIv.substring(0, 64));
    let iv = CryptoJS.enc.Hex.parse(hexKeyAndIv.substring(64, hexKeyAndIv.length));
    return CryptoJS.AES.encrypt(originWordArray, hexKey, {iv: iv}).toString();
  } 
  catch (error) {
    throw error;
  }

} }

C# decryption (is uses the same private variables that are mentioned in encryption) C# 解密(使用与加密中提到的相同的私有变量)

public string Decrypt(string encrypted, string key)
{
    try
    {
        encrypted = encrypted.Replace(" ", "+");
        byte[] cipherBytes = Convert.FromBase64String(encrypted);
        using (var encryptor = Aes.Create())
        {
            encryptor.Padding = Padding;
            var pdb = new Rfc2898DeriveBytes(key, Salt);
            encryptor.Key = pdb.GetBytes(KeyCB);
            encryptor.IV = pdb.GetBytes(IvCB);
            using var ms = new MemoryStream();
            using (var cs = new CryptoStream(ms, encryptor.CreateDecryptor(), Mode))
            {
                cs.Write(cipherBytes, 0, cipherBytes.Length);
                cs.Close();
            }
            encrypted = Encoding.Unicode.GetString(ms.ToArray());
        }
        return encrypted;
    }
    catch (Exception)
    {
        throw;
    }
}

I found an answer.我找到了答案。 Is decryptes exactly as it should, the same way as it does on C# side.完全按照它应该的方式解密,就像在 C# 端一样。

Angular decryption (it uses the same private fields as encrypted does) Angular 解密(它使用与加密相同的私有字段)

Decrypt(encrypted: string, key: string): string{    
  try {
    let keyWordArray = CryptoJS.enc.Utf8.parse(key);

    let keyAndIv = CryptoJS.PBKDF2(keyWordArray, this.SALT, { 
      keySize: 256/32 + 128/32, 
      iterations: this.ITERATIONS,
      hasher: CryptoJS.algo.SHA1 
    });
  
    let hexKeyAndIv = CryptoJS.enc.Hex.stringify(keyAndIv);

    let hexKey = CryptoJS.enc.Hex.parse(hexKeyAndIv.substring(0, 64));
    let iv = CryptoJS.enc.Hex.parse(hexKeyAndIv.substring(64, hexKeyAndIv.length)); 
                                                   
    let decryptedWordArray = CryptoJS.AES.decrypt(encrypted, hexKey, {iv: iv});
    return CryptoJS.enc.Utf16LE.stringify(decryptedWordArray);   
  } 
  catch (error) {
    throw error;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM