1

I am trying to encrypt a string "1" using key = "secret_key" and text "11869021012". Earlier I had written this in nodejs. now I want to port this to python. but here surprisingly both are giving different outputs.

var crypto = require('crypto');

function getBytes (str) {
  let bytes = [], char;
  str = encodeURI(str);
  while (str.length) {
    char = str.slice(0, 1);
    str = str.slice(1);

    if ('%' !== char) {
      bytes.push(char.charCodeAt(0));
    } else {
      char = str.slice(0, 2);
      str = str.slice(2);

      bytes.push(parseInt(char, 16));
    }
  }
  return bytes;
};


function getIV (str, bytes){
    iv = getBytes(str);
    if(!bytes) bytes = 16;
    for(let i=iv.length;i<bytes;i++) {
      iv.push(0);
    }
    return Buffer.from(iv);
};

function getKey (pwd){
    pwd = Buffer.from(getBytes(pwd), 'utf-8');
    let hash = crypto.createHash('sha256');
    pwd = hash.update(pwd).digest();
    return pwd;
};

function createCipherIV (algorithm, input_key, iv_input, text){
    let iv = getIV(iv_input);
    let key = getKey(input_key);
    let cipher = crypto.createCipheriv(algorithm, key, iv);
    let encrypted = cipher.update(text)
    encrypted += cipher.final('base64');
    return encrypted;
}

output = createCipherIV('aes256', 'secret_key', '11869021012', '1') 
console.log(output)

This produces the output: s6LMaE/YRT6y8vr2SehLKw==

python code:

# AES 256 encryption/decryption using pycrypto library
import base64
import hashlib

from Crypto.Cipher import AES
from Crypto import Random

BLOCK_SIZE = 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

password = "secret_key"

def encrypt(raw, password):
    private_key = hashlib.sha256(bytearray(password, "utf-8")).digest()
    raw = pad(raw)
    iv = b'11869021012\x00\x00\x00\x00\x00'
    cleartext = bytearray(raw, 'utf-8')
    cipher = AES.new(private_key, AES.MODE_CBC, iv)

    return base64.b64encode(iv + cipher.encrypt(cleartext))

# First let us encrypt secret message
encrypted = encrypt("1", password)
print(encrypted)

This produces the output: MTE4NjkwMjEwMTIAAAAAALOizGhP2EU+svL69knoSys=

I have used aes256 algorithm here for encrypting message. Clearly they are very close, but node seems to be padding the output with some extra bytes. Any ideas how I can get the two to interoperate?

6
  • You should match the mode of operations, in short everything. const algorithm = 'aes-256-cbc'; in JS if you want to use CBC mode. Commented Mar 18, 2019 at 17:22
  • even after using 'aes-256-cbc' I am getting some output Commented Mar 18, 2019 at 17:26
  • Because there is no encryption in python, only base64 encoding. Commented Mar 18, 2019 at 17:29
  • is there as we I am doing cipher.encrypt(cleartext)) . right? Commented Mar 19, 2019 at 5:33
  • Didn't Rob's answer solve your problem? Commented Mar 19, 2019 at 8:39

1 Answer 1

1

First, in a secure crypto system, you should expect the output to be different every time you encrypt, even using the same code. That fact that yours doesn't indicates it's an insecure cipher. Typically this is done by adding a random IV.

Your IV is "11869021012", which is horrible (because it's not random, and not even 16 bytes), but it does seem you're using it the same way in both, so that's fine.

Your password is the SHA-256 of a string, which is a horrible way to create a key, but still, you seem to be doing it the same way in both cases, so that's fine.

Your problem is that the Python code emits the IV followed by the cipher text. Your JS code does not emit the IV; it only emits the cipher text. So you probably meant this in the Python:

return base64.b64encode(cipher.encrypt(cleartext))

Or you need to rework the JavaScript to glue together the IV and the cipher text before Base64 encoding.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @rob-napier My bad. I was adding iv extra. Now getting similar output.

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.