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);
}