brix / crypto-js

JavaScript library of crypto standards.
Other
15.89k stars 2.39k forks source link

Issues passing secret key as bytearray to AES encrypt/decrypt #419

Closed anoxxxy closed 2 years ago

anoxxxy commented 2 years ago

Hi everyone, I got some python AES encrypt/decrypt code (works good) which I would like to use with CryptoJS AES encrypt/decrypt. But I am having issues with CryptoJS to output the same result as I get in Python 2.7.

I would like to pass secret key/password as bytearray for AES encryption/decryption.

Python 2.7 code:

from Crypto.Cipher import AES
from Crypto.Hash import MD4
from base64 import b64encode, b64decode
import hashlib
import datetime
from re import sub
import os
from Crypto.Util.Padding import pad,unpad

BLOCK_SIZE = 32

INTERRUPT = u'\u0001'.encode("utf8") #Moved here
PAD = u'\u0000'.encode("utf8") #Moved here
IV = u'12345678abcdefgh'.encode("utf8") #Moved here

def AddPadding(data, interrupt, pad, block_size):
    new_data = ''.join([data, interrupt])
    new_data_len = len(new_data)
    remaining_len = block_size - new_data_len
    to_pad_len = remaining_len % block_size
    pad_string = pad * to_pad_len
    return ''.join([new_data, pad_string])
def StripPadding(data, interrupt, pad):
    return data.rstrip(pad).rstrip(interrupt)

def EncryptWithAES(SECRET_KEY, plaintext_data):
        #Need to hash the "password" to be 32 bit.
        SECRET_KEY = hashlib.sha256(SECRET_KEY).digest()
        encrypt_cipher = AES.new(SECRET_KEY, AES.MODE_CBC, IV) #Moved here
        plaintext_padded = AddPadding(plaintext_data, INTERRUPT, PAD, BLOCK_SIZE)
        encrypted = encrypt_cipher.encrypt(plaintext_padded)

        return b64encode(encrypted)

def DecryptWithAES(SECRET_KEY, encrypted_data):
        #Need to hash the "password" to be 32 bit.
        SECRET_KEY = hashlib.sha256(SECRET_KEY).digest()

        decrypt_cipher = AES.new(SECRET_KEY, AES.MODE_CBC, IV) #Moved here
        decoded_encrypted_data = b64decode(encrypted_data)

        decrypted_data = decrypt_cipher.decrypt(decoded_encrypted_data)

        return StripPadding(decrypted_data, INTERRUPT, PAD)

text=EncryptWithAES("mypassword","some message")
#prints "LnuobSltiAKy6ZnneMAsLYVIP29A09PKYju0tOB5M/k="

text=DecryptWithAES("mypassword","LnuobSltiAKy6ZnneMAsLYVIP29A09PKYju0tOB5M/k=")
#prints "some message"

I followed this post https://github.com/brix/crypto-js/issues/317#issuecomment-702343201 hoping that it could help me but without success.

var CryptoJS = require('crypto-js');

let data = 'some message'
let secret_key = new Uint8Array(Buffer.from('mypassword'))
let iv = '12345678abcdefgh'

const encrypted = CryptoJS.AES.encrypt(data, secret_key, {
  iv: iv,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.ZeroPadding,
});

const base64encrypted = encrypted.toString(CryptoJS.enc.Base64)   // putting CryptoJS.enc.Base64 throws a TypeError: wordArray.clamp is not a function
console.log('base64encrypted: ' + base64encrypted)

const decrypted = CryptoJS.AES.decrypt(base64encrypted, secret_key, {
  iv: iv,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.ZeroPadding,
})

const base64decrypted = decrypted.toString(CryptoJS.enc.Base64) 
console.log('base64decrypted: ' + base64decrypted)

The important part is that the SECRET_KEY in the Python code, which is passed to AES encrypt/decrypt with hashlib.sha256(SECRET_KEY).digest() converting it to bytearray. I have tried to solve it by converting the secret_key to bytearray in the encrypt/decrypt part.

Is there anyone there who can help me or guide me so I can solve this?

Regards Anoxy

anoxxxy commented 2 years ago

issue solved by using the library https://github.com/ricmoo/aes-js/

regards