1

I have got this piece of python code which I need to translate into nodejs. The python code uses pycrypto from encryption. On the nodejs side, I am using the native crypto module. There seems to be a mismatch between the encrypted strings.

from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import json

raw_key = [0x58, 0x86, 0x17, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x28, 0xa4, 0x5a]
key = str(bytearray(raw_key))

raw_iv =  [0x34, 0x2e, 0x17, 0x99, 0x6d, 0x19, 0x3d, 0x28, 0xdd, 0xb3, 0xa2, 0x69, 0x5a, 0x2e, 0x6f, 0x1b]
iv = str(bytearray(raw_iv))

text = json.dumps({ "a": 1, "b": 2 })

cryptor = AES.new(key, AES.MODE_CBC, iv)
length = 16
count = len(text)
add = length - (count % length)
text = text + ('\0' * add)
encrypted = cryptor.encrypt(text);
print b2a_hex(encrypted)

The above python code outputs

5c72b1a394654b6dab9ea8fdd90fe56b92141d74cb32ac65ede4d3154801bb57

whereas the below nodejs code

const crypto = require('crypto');

const KEY = Buffer.from([0x58, 0x86, 0x17, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x28, 0xa4, 0x5a]);
const IV = Buffer.from([0x34, 0x2e, 0x17, 0x99, 0x6d, 0x19, 0x3d, 0x28, 0xdd, 0xb3, 0xa2, 0x69, 0x5a, 0x2e, 0x6f, 0x1b]);

const text = JSON.stringify({ a: 1, b: 2 });

const cipher = crypto.createCipheriv('aes-128-cbc', KEY, IV);
cipher.setAutoPadding(true);
const encrypted = Buffer.concat([cipher.update(text, 'utf-8'), cipher.final()]);
console.log(encrypted.toString('hex'));

outputs

d6a0dbc6df2a1038036e4db985f9ca10

Why don't they match? Am I doing something wrong?

5
  • 1
    It seems you are missing this concatenation on nodejs code: text = text + ('\0' * add) ... Commented Jul 21, 2017 at 3:10
  • Here you have a good example about the encryption with AES on nodejs: stackoverflow.com/questions/18236761/… Commented Jul 21, 2017 at 3:12
  • But doesn't setAutoPadding(true) automatically adds the missing characters? Commented Jul 21, 2017 at 3:16
  • Oh, ok... Sorry. But did you look to the content of the link? Commented Jul 21, 2017 at 3:47
  • I would suggest that you change the padding scheme in Python instead of node.js. Commented Jul 21, 2017 at 5:16

1 Answer 1

2

There are two issues here:

  1. Node's automatic padding is PKCS padding. Your python code is using null bytes for padding instead, which is a different format. The node documentation even explicitly mentions disabling auto padding in order to use null byte padding.

  2. The JSON is formatted slightly differently between node and python. Javascript's JSON.stringify() removes all unnecessary whitespace, whereas python leaves some whitespace (e.g. between elements in an array/object). The easiest solution to this will probably be to change the python code to specify an explicit separators option: json.dumps({ "a": 1, "b": 2 }, separators=(',', ':')), since the javascript's JSON.stringify() isn't as flexible when it comes to changing the formatting in this way.

The node code below shows that by matching the JSON output and using the proper padding, you will get the same hex output as python:

const crypto = require('crypto');

const KEY = Buffer.from([0x58, 0x86, 0x17, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x28, 0xa4, 0x5a]);
const IV = Buffer.from([0x34, 0x2e, 0x17, 0x99, 0x6d, 0x19, 0x3d, 0x28, 0xdd, 0xb3, 0xa2, 0x69, 0x5a, 0x2e, 0x6f, 0x1b]);

var text = '{"a": 1, "b": 2}';

const cipher = crypto.createCipheriv('aes-128-cbc', KEY, IV);
cipher.setAutoPadding(false);

var length = 16;
var count = Buffer.byteLength(text);
var add = length - (count % length);
if (add > 0)
  text += '\0'.repeat(add);

const encrypted = Buffer.concat([cipher.update(text, 'utf-8'), cipher.final()]);
console.log(encrypted.toString('hex'));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.