HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

PHP mcrypt AES encryption wrapper

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
encryptionmcryptaesphpwrapper

Problem

There are two keys: the main is aes128 and the second is XTEA, used just for randomization of data inside the AES. Randomization is done with secret random key that is not know even if someone knows exactly what is encrypted. Also the key is produced by doing hash many number of times and this hash is salted with the iv so it is not possible to make a dictionary attack with precomputed hashes.

```
function aes128ctr_en($data,$key,$hash_rounds = 0) {
//iv is created
$iv = mcrypt_create_iv(16,MCRYPT_DEV_URANDOM);
//internal secret random string is created so no one knows what
//is exactly encoded by main cipher
$xtea = mcrypt_create_iv(16,MCRYPT_DEV_URANDOM);
//password is hashed in many rounds to prevent dictionary attack,
//hashing is done with individual iv for hmac so it make no sense to use
//precalculated hashes
for($i=0;$i<=$hash_rounds;++$i) $key = hash_hmac('sha256',$key,$iv,true);
//string is randomized for use in aes, so no one knows what actually will be encoded
//this is not actual encoding so password is stored inside with xtea encoded string,
//second half of this password is used as IV for xtea
//again: THIS IS NOT ACTUAL ENCODING
$data = $xtea.mcrypt_encrypt('xtea',$xtea,$data,'ofb',substr($xtea,8));
//hash is added to check if return string is really what we looked for,
//must match with string on decoding
$data = hash('md5',$data,true).$data;
//actual encoding, IV is prepended to encrypted string
return $iv.mcrypt_encrypt('rijndael-128',$key,$data,'ctr',$iv);
}

function aes128ctr_de($data,$key,$hash_rounds = 0) {
$iv = substr($data,0,16);
$data = substr($data,16);
for($i=0;$i<=$hash_rounds;++$i) $key = hash_hmac('sha256',$key,$iv,true);
$data = mcrypt_decrypt('rijndael-128',$key,$data,'ctr',$iv);
$md5 = substr($data,0,16);
$data = substr($data,16);
if (hash('md5',$data,true)!==$md5) return false;
$xtea = substr($data,0,16);
$data = subst

Solution

You should use a key strengthening function like PKBDF2, scrypt or bcrypt to generate a key from the password.
The part with XTEA is useless: you're relying on security through obscurity.
You shouldn't hash before encrypting if you want to ensure the data has not been tampered with. Use HMAC SHA-256 on the encrypted data.

And finally: don't write your own crypto algorithm. Use well known and audited solutions.

Context

StackExchange Code Review Q#5915, answer score: 8

Revisions (0)

No revisions yet.