最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Compatibility between node crypto and crypto-js encryption and decryption - Stack Overflow

programmeradmin0浏览0评论

How do I properly encrypt/decrypt data between node.js with the crypto module (server side) and crypto-js (client side, react-native)?

NOTE: I'm using cryptojs in a react-native project, thus I can't use crypto on client. replacing crypto server side is not an option for me.

Server-side code:

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

Client-side code

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

How do I properly encrypt/decrypt data between node.js with the crypto module (server side) and crypto-js (client side, react-native)?

NOTE: I'm using cryptojs in a react-native project, thus I can't use crypto on client. replacing crypto server side is not an option for me.

Server-side code:

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

Client-side code

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
Share Improve this question edited Jun 27, 2016 at 9:31 gevorg 5,0655 gold badges38 silver badges54 bronze badges asked Feb 21, 2016 at 5:28 Jesus Leonardo ZorrillaJesus Leonardo Zorrilla 331 gold badge1 silver badge3 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

Your "password" (it is used as a key instead of a password) has two different encodings on client-side and server-side. On the client, you're parsing it as Hex, but on the server, you're passing it as a binary string, which is used as-is.

You either need parse it on the server (now it is AES-128 and not AES-256):

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

Or change the encoding on the client (from AES-128 to 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 "";
    }
  }

You still have security problems:

  • The IV has to be randomly chosen for every encryption under the same key to achieve semantic security. It doesn't have to be secret, so you can simply send it along with the ciphertext. It's mon to prepend it to the ciphertext and slice it off before decryption.

  • It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible. This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme with a strong MAC like HMAC-SHA256, which CryptoJS provides.

Here is the example node js crypto ( https://nodejs/api/crypto.html) and related encryption and decryption in crypto.js (https://github./brix/crypto-js).

Gist - https://gist.github./yoavniran/c78a0991e0152b306c25

//CryptoJS example
var key = "H98zM6i/55yNJfkFsbu0HrzlFo17FtR9";
var iv = key.slice(0, 16);
//Create Key
key = CryptoJS.enc.Utf8.parse(key);
//Get Iv
iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted = CryptoJS.AES.encrypt("testtest", key,{ iv: iv});
//Encrypt string
var encrypted_data = encrypted.toString();
console.log(encrypted_data)
var decrypted = CryptoJS.AES.decrypt(encrypted_data, key,{ iv: iv});
var decrypted_data = decrypted.toString(CryptoJS.enc.Utf8)
console.log(decrypted_data)


////Node JS example
  var key = "H98zM6i/55yNJfkFsbu0HrzlFo17FtR9";
  var iv = key.slice(0, 16);
  function encryptText(cipher_alg, key, iv, text, encoding) {
      var cipher = crypto.createCipheriv(cipher_alg, key, iv);
      encoding = encoding || "binary";
      var result = cipher.update(text,'utf8',  encoding);
      result += cipher.final(encoding);
      return result;
  }
  function decryptText(cipher_alg, key, iv, text, encoding) {
      var decipher = crypto.createDecipheriv(cipher_alg, key, iv);
      encoding = encoding || "binary";
      var result = decipher.update(text, encoding);
      result += decipher.final();
      return result;
  }
var encText = encryptText('aes256', key, iv, "testtest1", "base64");
console.log("encrypted text = " + encText);
var decText = decryptText('aes256', key, iv, encText, "base64");
console.log("decrypted text = " + decText);
发布评论

评论列表(0)

  1. 暂无评论