在 JavaScript 中从 C# 重现 AES 解密方法 [英] Reproduce AES decryption method from C# in JavaScript

查看:30
本文介绍了在 JavaScript 中从 C# 重现 AES 解密方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 JavaScript 中重现以下 C# 解密方法.

I am trying to reproduce the following C# decryption method in JavaScript.

此方法用于解密短字符串:姓名、地址、电子邮件地址等.

This method is used to decrypt short strings: names, addresses, email addresses, etc.

感觉非常接近,因为我能够成功"解密的字符串似乎已部分解密.

It feels tantalisingly close, because the strings I have been able to "successfully" decrypt seem partially decrypted.

例如,一些电子邮件看起来像这样:x"R Îd¹1gtWÈ2)web@example.com

For instance, some of the emails look like this: x"R�Îd¹1gtWÈ2)web@example.com

public static readonly byte[] INIT_VECTOR = { 0x00, 0x00, ... };

public static string Decrypt(string cipherText) {

  string EncryptionKey = "Some Encryption Key";

  byte[] cipherBytes = Convert.FromBase64String(cipherText);

  using (Aes encryptor = Aes.Create())
  {
​
    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, INIT_VECTOR);

    encryptor.Key = pdb.GetBytes(32);
    encryptor.IV = pdb.GetBytes(16);

    using (MemoryStream ms = new MemoryStream())
    {
      using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
      {
        cs.Write(cipherBytes, 0, cipherBytes.Length);
        cs.Close();
      }
      cipherText = Encoding.Unicode.GetString(ms.ToArray());
    }
  }

  return cipherText;
}

JavaScript

import atob from 'atob';
import forge from 'node-forge';

const InitVector = [0x00, ...];
const EncryptionKey = 'Some Encryption Key';

const iv = Buffer.from(InitVector).toString();

const convertBase64StringToUint8Array = input => {
  const data = atob(input);
  const array = Uint8Array.from(data, b => b.charCodeAt(0));

  return array;
};

const decrypt = cipher => {
  const cipherArray = convertBase64StringToUint8Array(cipher);

  const key = forge.pkcs5.pbkdf2(EncryptionKey, iv, 1000, 32);

  const decipher = forge.cipher.createDecipher('AES-CBC', key);

  decipher.start({ iv });

  decipher.update(forge.util.createBuffer(cipherArray, 'raw'));

  const result = decipher.finish();

  if (result) {
    return decipher.output.data;
  } else {
    return false;
  }
};

推荐答案

感谢 kelalaka 我设法解决了这个问题!

Thanks to kelalaka I managed to figure this out!

这是我最终得到的代码.

This was the code I ended up with.

import atob from 'atob';
import forge from 'node-forge';

const InitVector = [0x00, ...];
const EncryptionKey = 'Some Encryption Key';

const initKey = Buffer.from(InitVector).toString(); // Changed this to `initKey`

const convertBase64StringToUint8Array = input => {
  const data = atob(input);
  const array = Uint8Array.from(data, b => b.charCodeAt(0));

  return array;
};

const decrypt = cipher => {
  const cipherArray = convertBase64StringToUint8Array(cipher);

  const key = forge.pkcs5.pbkdf2(EncryptionKey, iv, 1000, 32);

  /**
   * Added the following
   * Note the key size = 48
   *  This was due to the fact that the C# dictated that
   *  the IV was 16 bytes, starting at the end of the key.
   */
  const keyAndIV = forge.pkcs5.pbkdf2(encryptionKey, initKey, 1000, 32 + 16);

  /**
   * Therefore, we cut the iv from the new string
   */
  const iv = keyAndIV.slice(32, 32 + 16); // 16 bytes

  const decipher = forge.cipher.createDecipher(
    'AES-CBC',
    forge.util.createBuffer(key)
  );

  decipher.start({ iv });

  decipher.update(forge.util.createBuffer(cipherArray, 'raw'));

  const result = decipher.finish();

  if (result) {
    return decipher.output.data;
  } else {
    return false;
  }
};

这篇关于在 JavaScript 中从 C# 重现 AES 解密方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆