gpt4 book ai didi

javascript - 如何在 openssl 中解密使用自定义迭代和 key 大小的 CryptoJs3+ 库加密的文件

转载 作者:行者123 更新时间:2023-12-04 03:37:23 27 4
gpt4 key购买 nike

我有一个由 cryptojs 加密的文本文件(可能还有一些自定义 js 函数来迭代密码的哈希值),我想通过 openssl.exe 在 Windows 中解密它,而不是使用浏览器(当我提供密码)。看起来 cryptojs 使用了一些自定义的东西,比如使用 sha512 派生 key 并将其迭代 11512 次,如下面的 js 解密器所示,然后使用 evpkdf 迭代 484 次(我不知道这些东西是什么意思)。从 cryptojs 解密文件的代码片段如下,我需要 openssl exe -cli params 来执行此操作,而无需在浏览器中使用该 js 库。

function hex2a(t) { //hex to ascii
for (var e = t.toString(), i = "", n = 0; n < e.length && "00" !== e.substr(n, 2); n += 2) i += String.fromCharCode(parseInt(e.substr(n, 2), 16));
return i; }

function decoder(secret, passwrd) {
for (var i = CryptoJS.SHA512(passwrd), n = 0; n < 11512; n++)
i = CryptoJS.SHA512(i);
(CryptoJS.algo.AES.keySize = 32),
(CryptoJS.algo.EvpKDF.cfg.iterations = 1e4),
(CryptoJS.algo.EvpKDF.cfg.keySize = 32);
var r = CryptoJS.AES.decrypt(secret, i.toString());
return (out = hex2a(r)), out;
}

这是它调用函数并在文件成功解密时返回文件的时间。

var msg="base64 of the salted encrypted file via cryptojs"
function proceed() {
var pass=document.getElementById('textfield2').value;
a=decoder(msg, pass);
if (a.search('{version')>-1) {
document.getElementById('status').innerHTML="SUCCESS";
download("result.json",a);
} else {
document.getElementById('status').innerHTML="FAILED";
}

我已经尝试过这个(windows openssl.exe cli 1.1)并且得到了关于 -iter 和其他参数的错误。不知道如何给它 key 大小 32 和迭代和 evpkdf 以及 js 文件解密的任何内容。

OpenSSL.exe enc -aes-256-cbc -md md5 -d -pass pass:"simpletext" -in "tiny.bin" -out "result.txt"

最佳答案

由于以下几个原因,原则上不可能使用 OpenSSL 进行解密:

  • 指定的 key 大小 AES.keySize = 32 定义了一个 128 字节的 key (这里没有直接传递,而是从密码派生的)。大概是打算使用 32 字节的 key ,但 CryptoJS 以字为单位指定 key 大小,其中一个字由 4 个字节组成。
    AES 仅为 16/24/32 字节 key 定义,即。 e.不适用于所使用的 128 字节 key 。尽管该 key 对于 AES 无效,但 CryptoJS 会由于错误 (Issue #293) 处理此 key 。
    从 key 大小直接得出轮数,结果为 38 ( source code )。但是,AES 仅为轮数 10 (AES-128)、12 (AES-192) 和 14 (AES-256) (AES, Security) 定义。因此,生成的密文与 AES 不兼容,即通常不可能使用 AES 兼容工具(尤其是 OpenSSL)进行解密。
    要使用 OpenSSL 进行解密,AES.keySize 需要具有值 4/6/8 之一,对应于允许的轮数 10/12/14 或 AES-128/192/256。因此,配置 AES.keySize = 32 是所有 AES 兼容工具(如 OpenSSL)的 KO 标准。

  • CryptoJS 使用 OpenSSL 函数 EVP_BytesToKey() 进行 key 派生。但是,OpenSSL 不支持指定的迭代计数 EvpKDF.cfg.iterations = 1e4 用于使用 EVP_BytesToKey() 进行 key 派生,只有值 1 ( here, last part )。
    更现代的 OpenSSL 版本(从 1.1.1 开始)具有选项 -iter ,但这仅与 key 派生 PBKDF2 结合使用,即如果指定了 -iter , 自动使用 PBKDF2 而不是 EVP_BytesToKey(),后者与 CryptoJS 不兼容。
    要使用 OpenSSL 进行解密,EvpKDF.cfg.iterations 将需要具有值 1。因此,配置 EvpKDF.cfg.iterations = 1e4 是 OpenSSL 的 KO 标准。

  • 传递给 CryptoJS 的密码是通过使用 SHA512 进行多次散列从原始密码派生出来的。正如 Artjom B. 的评论中已经解释的那样,这不能单独使用 OpenSSL 来实现,但它至少可以作为脚本的一部分。

  • EvpKDF.cfg.keySize参数对加解密没有影响,可以忽略。

如果在发布的代码中使用兼容值而不是不兼容值,例如CryptoJS.algo.AES.keySize = 8CryptoJS.algo.EvpKDF.cfg.iterations = 1,可以使用 OpenSSL 解密。以下示例使用具有兼容值的发布代码并执行加密和解密。密文可以用OpenSSL解密:

//
// Your code
//
function hex2a(t) {
for (var e = t.toString(), i = "", n = 0; n < e.length && "00" !== e.substr(n, 2); n += 2) i += String.fromCharCode(parseInt(e.substr(n, 2), 16));
return i;
}

function decoder(secret, passwrd) {
for (var i = CryptoJS.SHA512(passwrd), n = 0; n < 11512; n++) i = CryptoJS.SHA512(i);
CryptoJS.algo.AES.keySize = 8; // compatible with OpenSSL: 4/6/8, corresponds to AES-128/192/265
CryptoJS.algo.EvpKDF.cfg.iterations = 1; // compatible with OpenSSL: 1
CryptoJS.algo.EvpKDF.cfg.keySize = 123; // ignored
var r = CryptoJS.AES.decrypt(secret, i.toString());
return (out = hex2a(r)), out;
}

//
// The encryption counterpart
//
function encrypt(secret, passwrd) {
for (var i = CryptoJS.SHA512(passwrd), n = 0; n < 11512; n++) i = CryptoJS.SHA512(i);
CryptoJS.algo.AES.keySize = 8;
CryptoJS.algo.EvpKDF.cfg.iterations = 1;
CryptoJS.algo.EvpKDF.cfg.keySize = 456;
console.log("CryptoJS input passphrase:\n", i.toString().replace(/(.{56})/g,'$1\n'));
var ciphertext = CryptoJS.AES.encrypt(secret, i.toString());
return ciphertext;
}

//
// Encryption, decryption
//
var ciphertext = encrypt('The quick brown fox jumps over the lazy dog', 'my initial passphrase');
var decryptedData = decoder(ciphertext, 'my initial passphrase');
console.log("Ciphertext:\n", ciphertext.toString().replace(/(.{56})/g,'$1\n'));
console.log("Plaintext:\n", decryptedData.replace(/(.{56})/g,'$1\n'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

可能的输出:

CryptoJS input passphrase: 7bff3331f9dcfbb2e1c5b6cb4170689db91fe5b12258d59672fe0e9ce61780c61f3e6dc324e58cc2170c6a8010083aafe07930708ee63c0022a7e9bce784c4c5
Ciphertext: U2FsdGVkX1/3SLTOsvc6CoWfg53rR+l//pHiWstJibl5D5OopIFWVmhUDhEpj7zBZRjA1vQiIoU2F5qR1v8NEw==
Plaintext: The quick brown fox jumps over the lazy dog

密文可以用下面的OpenSSL语句解密(直接使用派生密码):

openssl enc -aes-256-cbc -d -a -A -in <path to ciphertext file> -md md5 -pass pass:7bff3331f9dcfbb2e1c5b6cb4170689db91fe5b12258d59672fe0e9ce61780c61f3e6dc324e58cc2170c6a8010083aafe07930708ee63c0022a7e9bce784c4c5 

当使用与这些参数不同的参数时(例如 AES.keySize = 32EvpKDF.cfg.iterations = 1e4),解密通常会失败并显示解密错误(即使使用 -iter 10000)。

关于javascript - 如何在 openssl 中解密使用自定义迭代和 key 大小的 CryptoJs3+ 库加密的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66657689/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com