javascript CryptoJS AES解密十六进制字符串?

gwbalxhn  于 2023-08-02  发布在  Java
关注(0)|答案(2)|浏览(311)

这是问题Trying to print hex string with CryptoJS的第二部分
基本上,我有一个使用CryptoJS加密消息并将密码文本作为十六进制字符串输出的函数。

function EncryptAES(text, key) {
  var encrypted = CryptoJS.AES.encrypt(text, key);
  return encrypted.ciphertext.toString()
}

字符串
我想写一个函数DecryptAES,它接受十六进制字符串、密钥和salt(我显然需要这些),并返回原始明文。问题是我不知道如何将十六进制字符串转换为CryptoJS.AES.decrypt可以接受的形式,而且我在文档中找不到任何地方实际解释如何做到这一点。也许我忽略了什么。请帮帮我

a1o7rhls

a1o7rhls1#

CryptoJS在内部使用WordArray数据类型,并提供编码器进行转换。如果你想将一个十六进制编码的字符串转换为WordArray,可以使用十六进制编码器,如下所示:

CryptoJS.enc.Hex.parse(<your hex encoded string>)

字符串
或者反过来

<your WordArray>.toString(CryptoJS.enc.Hex)


或者简称

<your WordArray>.toString()


此外,CryptoJS.AES.encrypt()返回一个CipherParams对象,其中封装了密文和salt等。这个CipherParams对象将被传递给CryptoJS.AES.decrypt()进行解密。
有了这个,你想要的可以实现如下:

function EncryptAES(text, key) {
    var encrypted = CryptoJS.AES.encrypt(text, key);
    return {ciphertext: encrypted.ciphertext.toString(), salt: encrypted.salt.toString()}
}

function DecryptAES(ciphertext, salt, key){
    var decrypted = CryptoJS.AES.decrypt({ciphertext:CryptoJS.enc.Hex.parse(ciphertext), salt:CryptoJS.enc.Hex.parse(salt)}, key); 
    return decrypted;
}

var {ciphertext, salt} = EncryptAES('The quick brown fox jumps over the lazy dog', 'my passphrase');
console.log('Ciphertext (hex): ', ciphertext);
console.log('Salt (hex): ', salt);

var decrypted = DecryptAES(ciphertext, salt, 'my passphrase');
console.log('Decrypted: ', decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

但是,有一种更简单的方法来处理salt和密文。对于CipherParams对象,.toString()以Base64编码的OpenSSL格式返回数据,该格式包括Salted__的十六进制编码,后跟8字节的salt和实际的密文。CryptoJS.AES.decrypt()隐式地将这样的Base64字符串转换为CipherParams对象:

var encrypted = CryptoJS.AES.encrypt('The quick brown fox jumps over the lazy dog', 'my passphrase').toString();
console.log("Salt, ciphertext (OpenSSL format, Base64): ", encrypted);

var decrypted = CryptoJS.AES.decrypt(encrypted, 'my passphrase');
console.log("Decrypted: ", decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
c0vxltue

c0vxltue2#

CryptoJS期望其加密数据具有某种格式。如果只提供密文的十六进制字符串,则在解密时需要重新构造此格式化数据。下面是一个例子:

function EncryptAES(text, key) {
  var encrypted = CryptoJS.AES.encrypt(text, key);
  return encrypted.toString();  // this will be a string includes salt, iv and ciphertext
}

function DecryptAES(ciphertext, key) {
  var decrypted = CryptoJS.AES.decrypt(ciphertext, key);
  return decrypted.toString(CryptoJS.enc.Utf8); // decode to original text
}

字符串
在EncryptAES函数中,通过调用encrypted.toString(),它将生成一个包含salt、iv和密文的字符串。当我们解密它时,我们不需要单独处理盐和iv。
但是,如果您只处理密文(十六进制字符串),则可以使用以下命令对其进行解密:

function DecryptFromHex(ciphertextHex, key, iv) {
  var cipherParams = CryptoJS.lib.CipherParams.create({
    ciphertext: CryptoJS.enc.Hex.parse(ciphertextHex)
  });
  var decrypted = CryptoJS.AES.decrypt(cipherParams, CryptoJS.enc.Utf8.parse(key), { iv: CryptoJS.enc.Utf8.parse(iv) });
  return decrypted.toString(CryptoJS.enc.Utf8);
}


DecryptFromHex获取十六进制密文字符串,将其解析回CryptoJS可以理解的格式,然后对其进行解密。请注意,key和iv也从UTF8解析为CryptoJS使用的WordArray格式。
确保用于decryption的密钥和iv与用于encryption的密钥和iv匹配。

相关问题