Short Answer: Decrypt first and then decompress if compression type is specified.
Longer answer:
After a little research I stumbled upon this example (sadly written javascript error in python not in javascript) but it covers the steps to do in more detail.
https://github.com/amzn/selling-partner-api-docs/issues/186#issuecomment-756108550
It contains both compressed or not compressed cases. Specifically for compressed it looks like this:
import gzip import requests from cryptography.hazmat.primitives import padding from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes def ase_cbc_decryptor(key, iv, encryption): cipher = Cipher(algorithms.AES(base64.b64decode(key)), modes.CBC(base64.b64decode(iv))) decryptor = cipher.decryptor() decrypted_text = decryptor.update(encryption) unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() unpaded_text = unpadder.update(decrypted_text) return unpaded_text + unpadder.finalize() def get_report_document_content(self, key, iv, url, compression_type=None): resp = requests.get(url=url) resp_content = resp.content decrypted_content = ase_cbc_decryptor(key=key, iv=iv, encryption=resp_content) if compression_type == 'GZIP': decrypted_content = gzip.decompress(decrypted_content) code = 'utf-8' if 'cp1252' in resp.headers.get('Content-Type', '').lower(): code = 'Cp1252' return decrypted_content.decode(code)
P.S. keep in mind you need to use AES in CBC mode
Short example here: https://gist.github.com/manuks/5cef1e536ef791e97b39
var keyhex = "8479768f48481eeb9c8304ce0a58481eeb9c8304ce0a5e3cb5e3cb58479768f4"; //length 32 var blockSize = 16; function encryptAES(input) { try { var iv = require('crypto').randomBytes(16); //console.info('iv',iv); var data = new Buffer(input).toString('binary'); //console.info('data',data); key = new Buffer(keyhex, "hex"); //console.info(key); var cipher = require('crypto').createCipheriv('aes-256-cbc', key, iv); // UPDATE: crypto changed in v0.10 // https://github.com/joyent/node/wiki/Api-changes-between-v0.8-and-v0.10 var nodev = process.version.match(/^v(\d+)\.(\d+)/); var encrypted; if( nodev[1] === '0' && parseInt(nodev[2]) < 10) { encrypted = cipher.update(data, 'binary') + cipher.final('binary'); } else { encrypted = cipher.update(data, 'utf8', 'binary') + cipher.final('binary'); } var encoded = new Buffer(iv, 'binary').toString('hex') + new Buffer(encrypted, 'binary').toString('hex'); return encoded; } catch (ex) { // handle error // most likely, entropy sources are drained console.error(ex); } } function decryptAES(encoded) { var combined = new Buffer(encoded, 'hex'); key = new Buffer(keyhex, "hex"); // Create iv var iv = new Buffer(16); combined.copy(iv, 0, 0, 16); edata = combined.slice(16).toString('binary'); // Decipher encrypted data var decipher = require('crypto').createDecipheriv('aes-256-cbc', key, iv); // UPDATE: crypto changed in v0.10 // https://github.com/joyent/node/wiki/Api-changes-between-v0.8-and-v0.10 var nodev = process.version.match(/^v(\d+)\.(\d+)/); var decrypted, plaintext; if( nodev[1] === '0' && parseInt(nodev[2]) < 10) { decrypted = decipher.update(edata, 'binary') + decipher.final('binary'); plaintext = new Buffer(decrypted, 'binary').toString('utf8'); } else { plaintext = (decipher.update(edata, 'binary', 'utf8') + decipher.final('utf8')); } return plaintext; } var input="testing"; var encrypted = encryptAES(input); console.info('encrypted:', encrypted); var decryped = decryptAES(encrypted); console.info('decryped:',decryped);