在 JavaScript 中解密 AES

İsa*_*llı 5 javascript aes

我正在用 Swift 语言使用 AES256 加密文本并将其输出为十六进制。我想用 JS 解密收到的这段代码,但无法得到结果。我尝试了 CryptoJS 库,但仍然无法得到我想要的结果。我想要的只是 js 代码,当我输入 IV、密码和密文时,它会给我解码版本。

const crypto = require("crypto");

var key = "";
const iv =  "";
const token = "";


function decrypt(token, iv, key) {
    const decrypter = crypto.createDecipheriv("aes-256-cbc", key, iv);
    let decrypted = decrypter.update(token, "hex", "utf8");
    decrypted += decrypter.final("utf8");
    return  decrypted
}

console.log(decrypt(token, iv, key));
Run Code Online (Sandbox Code Playgroud)

通过上面的 Node.js 代码,我实现了我想要的,但我想用普通的 JS 代码来实现,而不是使用 Node。我不想打扰服务器。如果您能提供帮助,我将非常高兴。

编辑:我正在 Swift 语言中使用 CryptoSwift 库。

func encryption(uuid: String, token: String) -> String {
    do {
        let aes = try AES(key: String(uuid.prefix(32)), iv: String(uuid.prefix(16)))
        
        let ciphertext = try aes.encrypt(Array(token.utf8))
        let encrypttext = ciphertext.toHexString()
        return encrypttext
    }
    catch {
        return "error"
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用下面站点中的代码使用 CryptoJS 做一些事情,但它不像 Node.js 中的代码那样工作。

编辑2:

  • 我一直在尝试不同的事情,但无法完全弄清楚。添加 PBKDF2 时出现错误。我不完全理解这个问题。

func encryption(uuid: String, token: String) -> String {
    do {
        let aes = try AES(key: String(uuid.prefix(32)), iv: String(uuid.prefix(16)))
        
        let ciphertext = try aes.encrypt(Array(token.utf8))
        let encrypttext = ciphertext.toHexString()
        return encrypttext
    }
    catch {
        return "error"
    }
}
Run Code Online (Sandbox Code Playgroud)
var password = "6268890F-9B58-484C-8CDC-34F9C6A9";
var iv = "6268890F-9B58-48";
var cipher = "79a247e48ac27ed33ca3f1919067fa64";

/*
var key = CryptoJS.PBKDF2(password, {
      keySize: 32
    });
*/

  var dec= CryptoJS.enc.Hex.parse(cipher);
  const decrypted = CryptoJS.AES.decrypt({
  ciphertext: dec 
},
   password, {
     iv: iv,
      mode: CryptoJS.mode.CBC, 
      padding: CryptoJS.pad.Pkcs7
      });

      console.log(decrypted.toString(CryptoJS.enc.Utf8));
Run Code Online (Sandbox Code Playgroud)

Top*_*aco 4

CryptoJS使用WordArrays,因此密钥、IV和密文必须进行相应的转换。为此,必须应用适当的编码器。此外,decrypt()期望密文作为CipherParams对象。

这会导致以下可能的CryptoJS实现:

var ciphertext = "79a247e48ac27ed33ca3f1919067fa64";
var key = "6268890F-9B58-484C-8CDC-34F9C6A9";
var iv = "6268890F-9B58-48";

var ciphertextWA = CryptoJS.enc.Hex.parse(ciphertext);
var keyWA = CryptoJS.enc.Utf8.parse(key);
var ivWA = CryptoJS.enc.Utf8.parse(iv);
var ciphertextCP = { ciphertext: ciphertextWA };

var decrypted = CryptoJS.AES.decrypt(
    ciphertextCP,
    keyWA, 
    { iv: ivWA }
);

console.log(decrypted.toString(CryptoJS.enc.Utf8)); // Apple
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

它在功能上与发布的 NodeJS 代码相同,也成功解密了测试数据。


关于评论中提出的有关编码的问题:
一般来说,解密方必须了解用于加密的编码。然而,在这种情况下,编码可以从发布的 NodeJS 代码中派生出来:

而且,所使用的数据与这些结论是一致的。


请注意,出于安全原因,可能不会使用静态 IV。相反,必须为每个加密生成一个随机 IV。
此外,即使密码长度正确,也不能将密码用作密钥。如果要使用密码,则需要派生密钥,例如使用 PBKDF2。
出于测试目的,数据当然足够了。