节点密码和encryption-jsencryption和解密之间的兼容性

如何正确使用encryption模块(服务器端)和crypto-js(客户端,react-native)在node.js之间encryption/解密数据?

注意:我在一个react-native项目中使用cryptojs,因此我不能在客户端上使用encryption。 replaceencryption服务器端不是我的select。

服务器端代码:

var Crypto = require("crypto"); var Cipher = { pass: "0123456789abcdef0123456789abcdef", iv: "0123456789abcdef", encript: function (msg) { try { var cipher = Crypto.createCipheriv("aes-256-cbc", this.pass, this.iv); var hash = cipher.update(msg, 'utf8', "hex"); var hex = hash + cipher.final("hex"); return hex; } catch (err) { console.error(err); return ""; } }, decript: function (hex){ try { var decipher = Crypto.createDecipheriv("aes-256-cbc", this.pass, this.iv); var dec = decipher.update(hex, "hex", 'utf8'); return dec + decipher.final('utf8'); } catch (err) { console.error(err); return ""; } } } Cipher.encript("i have an apple"); // 577267026f88f82ea286baf6bf089acb Cipher.decript("577267026f88f82ea286baf6bf089acb"); // i have an apple 

客户端代码

 var CryptoJS = require("crypto-js"); var Cipher = { pass: CryptoJS.enc.Hex.parse("0123456789abcdef0123456789abcdef"), iv: CryptoJS.enc.Hex.parse("0123456789abcdef"), encript: function (msg) { try { var options = { mode: CryptoJS.mode.CBC, iv: this.iv}; var json = CryptoJS.AES.encrypt(msg, this.pass, options); return json.ciphertext.toString(CryptoJS.enc.Hex); } catch (err) { console.error(err); return ""; } }, decript: function (hex){ try { // ??????????????????????????????????? // ??????????????????????????????????? } catch (err) { console.error(err); return ""; } } } Cipher.encript("i have an apple"); // 405552d9a77ea9e29442057d27cd7aee Cipher.decript(?????); // I have no Idea 

你的“密码”(它被用作密钥而不是密码)在客户端和服务器端有两种不同的编码。 在客户端上,您将它parsing为hex,但是在服务器上,您将它作为二进制string传递,原样使用。

您需要在服务器上parsing它(现在是AES-128而不是AES-256):

 pass: new Buffer("0123456789abcdef0123456789abcdef", "hex"), 

或者更改客户端上的编码(从AES-128到AES-256):

 pass: CryptoJS.enc. Utf8 .parse("0123456789abcdef0123456789abcdef"), 

  encript: function (msg) { try { var options = { mode: CryptoJS.mode.CBC, iv: this.iv}; var json = CryptoJS.AES.encrypt(msg, this.pass, options); return json.ciphertext.toString(CryptoJS.enc.Hex); } catch (err) { console.error(err); return ""; } }, decript: function (hex){ try { var options = { mode: CryptoJS.mode.CBC, iv: this.iv}; var json = CryptoJS.AES.decrypt({ ciphertext: CryptoJS.enc.Hex.parse(hex) }, this.pass, options); return json.toString(CryptoJS.enc.Utf8); } catch (err) { console.error(err); return ""; } } 

您仍然有安全问题:

  • 为了实现语义安全,必须在同一个密钥下随机selectIV。 它不一定是保密的,所以你可以简单地把它和密文一起发送。 在密文之前加上密文并在解密之前将其切断是很常见的。

  • authentication你的密文是更好的,所以像填充甲骨文攻击这样的攻击是不可能的。 这可以通过authentication模式(如GCM或EAX),或使用具有强大MAC(如CryptoJS提供的HMAC-SHA256)的encryption后MACscheme来完成。