Interoperability between Python and CryptoJS/Google Apps Script (AES)

Description

Building on this solution, I am trying to achieve interoperability between Python (cryptography and not pycrypto/pycryptodome) and CryptoJS on Google Apps Script (GAS). I am able to successfully encrypt in CryptoJS/GAS and decrypt in Python, however, I am unable to reverse the process and encrypt in Python and decrypt in CryptoJS/GAS.

I suspect the problem may be padding.

This works: Encrypt in CryptoJS(GAS)/Decrypt in Python

Encrypt In CryptoJS/GAS:

function encryptForPython(){

  // Given Data      
  cleartext = "a secret message"
  var password = "lazydog";
  var salt = "salt";
  var iterations = 1000;

  // Begin
  var bytes = CryptoJS.PBKDF2(password, salt, { keySize: 256, iterations: iterations,hasher: CryptoJS.algo.SHA256 });
  var iv = CryptoJS.enc.Hex.parse(bytes.toString().slice(0, 32));
  var key = CryptoJS.enc.Hex.parse(bytes.toString().slice(32, 96));

  var ciphertext = CryptoJS.AES.encrypt(cleartext, key, { iv: iv });
  Logger.log(ciphertext.toString());}

Decrypt in Python:

from base64 import b64decode
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

# Given Data
password = "lazydog"
salt = "salt"
ciphertext = "fJgVCai7TDBtWEf+uM27tZ4gfxO84xFqylxu/3Eew8I="

# Begin
data = b64decode(ciphertext)

kdf = PBKDF2HMAC(
    # Check for bigger hashes here:
    #https://cryptojs.gitbook.io/docs/

    algorithm=hashes.SHA256(),
    length=256, #same as key size?
    salt=salt.encode("utf-8"),
    iterations=1000,
)

myBytes = kdf.derive(password.encode("utf-8"))
iv = myBytes[0:16]
key = myBytes[16:48]
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
decryptor = cipher.decryptor()
text = decryptor.update(data) + decryptor.finalize()
cleartext = text[:-text[-1]].decode("utf-8")
print(cleartext)

This doesn't work: Encrypt in CryptoJS(GAS)/Decrypt in Python

Encrypt in Python

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from base64 import b64encode

# Given Data
password = "lazydog"
salt = "salt"
cleartext = "a secret message"

# Begin 
kdf = PBKDF2HMAC(
    algorithm=hashes.SHA256(), # <==== YOU FUCKING MOTHERFUCKER! (Was SHA256)
    length=256, #same as key size?
    salt=salt.encode("utf-8"),
    iterations=1000,
)

keys = kdf.derive(password.encode("utf-8"))
iv = keys[0:16]
key = keys[16:48]

cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
encryptor = cipher.encryptor()
ct = encryptor.update(cleartext.encode("utf-8")) + encryptor.finalize()
ciphertext = b64encode(ct).decode()
print("Final Cipher Text: "+ciphertext)

# Sanity Check
decryptor = cipher.decryptor()
clear = decryptor.update(ct) + decryptor.finalize()
print("Sanity check: "+clear.decode())

Decrypt in CryptoJS/GAS

function decryptFromPython() {
  
  // Given Data
  var ciphertext = "fJgVCai7TDBtWEf+uM27tQ==";
  var password = "lazydog";
  var salt = "salt";
  var iterations = 1000;
  
  // Start
  var bytes = CryptoJS.PBKDF2(password, salt, { keySize: 256, iterations: iterations,hasher: CryptoJS.algo.SHA256 });
  var iv = CryptoJS.enc.Hex.parse(bytes.toString().slice(0, 32));
  var key = CryptoJS.enc.Hex.parse(bytes.toString().slice(32, 96));
  var decryptedWA = CryptoJS.AES.decrypt(ciphertext, key, { iv: iv});

   var cipherParams = CryptoJS.lib.CipherParams.create({
     ciphertext: CryptoJS.enc.Base64.parse(ciphertext )
  });
  var decryptedFromText = CryptoJS.AES.decrypt(cipherParams, key, { iv: iv});
  Logger.log(decryptedFromText.toString(CryptoJS.enc.Utf8))
}


from Recent Questions - Stack Overflow https://ift.tt/3hMAFrc
https://ift.tt/eA8V8J

Comments

Popular posts from this blog

Spring Elasticsearch Operations

Network Error and Timeout on Authorize.net JS

Object oriented programming concepts (OOPs)