crypto/crypto/ AESRecipes1


Python

from Crypto.Cipher import AES

def pad_pcs7(x):
  l = len(x)
  a = l % 16
  b = 16 - a
  c = bytes([b]*b)
  return x + c

def enc(plaintext,phrase,iterations=1977):
  salt = os.urandom(256)
  iv = os.urandom(16)
  key = hashlib.pbkdf2_hmac("sha512",phrase.encode("utf8"),salt,iterations,32)
  aes = AES.new(key, AES.MODE_CBC, IV=iv)
  bplaintext = plaintext.encode("utf8")
  bplaintext = pad_pcs7(bplaintext)
  ciphertext = aes.encrypt(bplaintext)
  ciphertext_b64 = b64e(ciphertext)
  obj = {
    "ciphertext": ciphertext_b64.decode("utf8"),
    "salt": salt.hex(),
    "iv": iv.hex(),
    "iterations": iterations
  }
  return obj

I use this, for example, to create SelfDecryptingWebpage's in Python which can be decrypted with Javascript (using CryptoJS).

Javascript

This is compatible with the Python encrypt above. Using cryptojs on my gitub

<script src="aes.js"></script>
<script src="sha512.js"></script>
<script src="pbkdf2.js"></script>
...
const enc = (passphrase,plaintext,iterations=1977) => {
  const salt = CryptoJS.lib.WordArray.random(256)
  const iv = CryptoJS.lib.WordArray.random(16)
  const key = CryptoJS.PBKDF2(passphrase, salt, { hasher: CryptoJS.algo.SHA512, keySize: 64/8, iterations})
  const encrypted = CryptoJS.AES.encrypt(plaintext, key, { iv })
  const ciphertext = encrypted.toString()
  const obj = { ciphertext, salt: salt.toString(CryptoJS.enc.Hex), 
    iv: iv.toString(CryptoJS.enc.Hex), iterations }
  return obj
}
const decrypt = (passphrase,obj) => {
  const { ciphertext, iterations } = obj
  const salt = CryptoJS.enc.Hex.parse(obj.salt)
  const iv = CryptoJS.enc.Hex.parse(obj.iv)
  const key = CryptoJS.PBKDF2(passphrase, salt, { hasher: CryptoJS.algo.SHA512, keySize: 64/8, iterations})
  const decrypted = CryptoJS.AES.decrypt(ciphertext, key, { iv })
  return decrypted.toString(CryptoJS.enc.Utf8)
}

Php

This may not be compatible with the above

function encrypt($plaintext, $password) {
    $method = "AES-256-CBC";
    $key = hash('sha256', $password, true);
    $iv = openssl_random_pseudo_bytes(16);

    $ciphertext = openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv);
    $hash = hash_hmac('sha256', $ciphertext . $iv, $key, true);

    return $iv . $hash . $ciphertext;
}

function decrypt($ivHashCiphertext, $password) {
    $method = "AES-256-CBC";
    $iv = substr($ivHashCiphertext, 0, 16);
    $hash = substr($ivHashCiphertext, 16, 32);
    $ciphertext = substr($ivHashCiphertext, 48);
    $key = hash('sha256', $password, true);

    if (!hash_equals(hash_hmac('sha256', $ciphertext . $iv, $key, true), $hash)) return null;

    return openssl_decrypt($ciphertext, $method, $key, OPENSSL_RAW_DATA, $iv);
}