0

I want to know that can I use this encrypt-decrypt script for password encryption and put it into database? And what will be the sql table password column structure(currently it is password varchar(32) NOT NULL). Please note that this script is using a 32-byte hexadecimal key as encryption key.

<?php

define('ENCRYPTION_KEY', '32-byte hexadecimal encryption key');

function mc_encrypt($encrypt, $key)
{
  $encrypt = serialize($encrypt);
  $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
  $key = pack('H*', $key);
  $mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
  $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
  $encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
  return $encoded;
}

function mc_decrypt($decrypt, $key)
{
  $decrypt = explode('|', $decrypt);
  $decoded = base64_decode($decrypt[0]);
  $iv = base64_decode($decrypt[1]);
  if(strlen($iv)!==mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC)){ return false; }
  $key = pack('H*', $key);
  $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
  $mac = substr($decrypted, -64);
  $decrypted = substr($decrypted, 0, -64);
  $calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
  if($calcmac!==$mac){ return false; }
  $decrypted = unserialize($decrypted);
  return $decrypted;
}
?>
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Shyam3089
  • 459
  • 1
  • 5
  • 20
  • A few notes: if you just want to verify passwords, you should not store the passwords *at all*, not even encrypted; for instance, read [this](http://stackoverflow.com/questions/401656/secure-hash-and-salt-for-php-passwords). Where would you store the encryption/decryption key? Other note: You are not using AES but Rijndael with a block size of 256. The encryption seems OK otherwise, even though it uses MAC-then-encrypt instead of encrypt-then-MAC. – Maarten Bodewes Jul 26 '14 at 16:03
  • Note that the key handling is very weird, it seems you can give it a 48 byte key and have the encryption key have the first 32 bytes and the HMAC key the last 16 bytes. But if you give it anything in between, the keys will overlap. Be sure you understand the key handling, or you may not be able to decrypt later on. – Maarten Bodewes Jul 26 '14 at 16:08
  • @owlstead.Thank you for the answer.The link you gave was really helpful.. – Shyam3089 Jul 26 '14 at 18:17
  • Also note that a site called [codereview](http://codereview.stackexchange.com) exists. – Maarten Bodewes Jul 26 '14 at 19:40
  • Note that you should always try and include a language tag. – Maarten Bodewes Aug 01 '14 at 13:56
  • Also see Openwall's [Portable PHP password hashing framework](http://www.openwall.com/phpass/) (PHPass). Its hardened against a number of common attacks on user passwords. – jww Oct 11 '14 at 23:24

1 Answers1

0

You should not store passwords - with or without encryption - unless strictly required (i.e. dealing with older protocols). Instead use a password hash function based on a PBKDF such as PBKDF2, bcrypt or scrypt.

Note that the encryption does not use AES but Rijndael with a block size of 256 bits. Also note that the key handling is suboptimal, it's easy to make mistakes with regards to the key parameter. Otherwise the code looks OK at first glance.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263