在Forge.js中解密CryptoJS AES数据(带密码)

时间:2016-03-25 02:55:14

标签: javascript encryption cryptography cryptojs

所以我有一段用密码加密字符串的代码。它使用CryptoJS AES加密函数(CryptoJS.AES.encrypt),看起来像这样......

CryptoJS.AES.encrypt(data, password).toString();

展望未来,我不想使用CryptoJS,因为它已被正式弃用/未维护,我宁愿使用Forge.js。我试图通过GitHub上的Forge.js文档来查找解决方案,但是找不到任何使用密码短语的内容而不是手动创建密钥& IV。

我在https://code.google.com/archive/p/crypto-js/看了一下CryptoJS档案,似乎如果encrypt函数传递了一个字符串作为第二个参数(键),它就被用作密码来导出一个关键和IV。但它没有详细说明它是如何做到的。

似乎base64对结果进行解码会给出一个以Salted__开头的字符串,然后是一个逗号然后加密的二进制文本blob,我甚至不确定如何将“salt”传递给Forge

我如何仅使用Forge.js解密此数据blob?

1 个答案:

答案 0 :(得分:4)

CryptoJS支持OpenSSL的EVP_BytesToKey功能,该功能通过一轮MD5从新生成的盐和密码中获取密钥和IV。 forge documentation page上有一个例子:

  

在node.js中使用forge来匹配openssl" enc"命令行工具   (注意: OpenSSL" enc"使用带有自定义键的非标准文件格式   推导函数和固定迭代计数为1,其中一些   考虑比OpenPGP / GnuPG等替代品更不安全:

<div class="body">
  <h2>
    Foo
  </h2>
  <div class="container">
    asdasds
  </div>
  <footer>sadasdsa</footer>
</div>

此示例针对Triple DES显示,但它对AES的工作方式相同。您只需将var forge = require('node-forge'); var fs = require('fs'); // openssl enc -des3 -in input.txt -out input.enc function encrypt(password) { var input = fs.readFileSync('input.txt', {encoding: 'binary'}); // 3DES key and IV sizes var keySize = 24; var ivSize = 8; // get derived bytes // Notes: // 1. If using an alternative hash (eg: "-md sha1") pass // "forge.md.sha1.create()" as the final parameter. // 2. If using "-nosalt", set salt to null. var salt = forge.random.getBytesSync(8); // var md = forge.md.sha1.create(); // "-md sha1" var derivedBytes = forge.pbe.opensslDeriveBytes( password, salt, keySize + ivSize/*, md*/); var buffer = forge.util.createBuffer(derivedBytes); var key = buffer.getBytes(keySize); var iv = buffer.getBytes(ivSize); var cipher = forge.cipher.createCipher('3DES-CBC', key); cipher.start({iv: iv}); cipher.update(forge.util.createBuffer(input, 'binary')); cipher.finish(); var output = forge.util.createBuffer(); // if using a salt, prepend this to the output: if(salt !== null) { output.putBytes('Salted__'); // (add to match openssl tool output) output.putBytes(salt); } output.putBuffer(cipher.output); fs.writeFileSync('input.enc', output.getBytes(), {encoding: 'binary'}); } // openssl enc -d -des3 -in input.enc -out input.dec.txt function decrypt(password) { var input = fs.readFileSync('input.enc', {encoding: 'binary'}); // parse salt from input input = forge.util.createBuffer(input, 'binary'); // skip "Salted__" (if known to be present) input.getBytes('Salted__'.length); // read 8-byte salt var salt = input.getBytes(8); // Note: if using "-nosalt", skip above parsing and use // var salt = null; // 3DES key and IV sizes var keySize = 24; var ivSize = 8; var derivedBytes = forge.pbe.opensslDeriveBytes( password, salt, keySize + ivSize); var buffer = forge.util.createBuffer(derivedBytes); var key = buffer.getBytes(keySize); var iv = buffer.getBytes(ivSize); var decipher = forge.cipher.createDecipher('3DES-CBC', key); decipher.start({iv: iv}); decipher.update(input); var result = decipher.finish(); // check 'result' for true/false fs.writeFileSync( 'input.dec.txt', decipher.output.getBytes(), {encoding: 'binary'}); } 更改为16。