0

I am rewriting code to be compatible with PHP 7.2. Old code is

public function encryptPasswordOld($password, $salt)
{
    $key = md5($salt);
    $result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $password, MCRYPT_MODE_ECB);
    return base64_encode($result);
}

New code should be according to my research something like this

public function encryptPasswordNew($password, $salt)
{
    $method = 'AES-256-ECB';
    $ivSize = openssl_cipher_iv_length($method);
    $iv = openssl_random_pseudo_bytes($ivSize);
    $key = md5($salt);
    $result = openssl_encrypt($password, $method, $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($result);
}

but I tried every combination of openssl_encrypt options: OPENSSL_RAW_DATA, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, OPENSSL_ZERO_PADDING, 0 and still ended up with different result as the old method returns

Michal Tinka
  • 165
  • 1
  • 9
  • See [Use openssl_encrypt to replace Mcrypt for 3DES-ECB encryption](http://stackoverflow.com/q/39467008/608639), [Can't decrypt using pgcrypto from AES-256-CBC but AES-128-CBC is OK](http://stackoverflow.com/q/43550818/608639), [MCrypt rijndael-128 to OpenSSL aes-128-ecb conversion](http://stackoverflow.com/q/45218465/608639), etc. Also see [Upgrading my encryption library from Mcrypt to OpenSSL](http://stackoverflow.com/q/43329513), [Replace Mcrypt with OpenSSL](http://stackoverflow.com/q/9993909/608639) and [Preparing for removal of Mcrypt in PHP 7.2](http://stackoverflow.com/q/42696657) – jww Feb 12 '18 at 12:16
  • @jww - based on some of your links I think that I am doing it right, people were using AES-128-ECB,... but I am using AES-256-ECB but still wrong result – Michal Tinka Feb 12 '18 at 13:09
  • The old looks kind of bent/broken to me. MD5 produces a digest of 128-bits. It is too short to use for an AES-256 key, which requires 256-bits. Do you know if Mcrypt automatically backfills with 0's? In the future, use [HKDF](https://tools.ietf.org/html/rfc5869) to extract the password entropy and expand the entropy for an AES-256 key. – jww Feb 13 '18 at 10:50
  • Also, for `openssl_encrypt`, you may need to turn off PKCS padding. Also see [EVP Symmetric Encryption and Decryption | Padding](https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption#Padding) on the OpenSSL wiki. I don't know how to do it with Mcrypt or PHP. The [`mcrypt-encrypt`](https://secure.php.net/manual/en/function.mcrypt-encrypt.php) page does say: *"OpenSSL also uses PKCS7 padding with CBC mode rather than mcrypt's NULL byte padding. Thus, mcrypt is more likely to make your code vulnerable to padding oracle attacks than OpenSSL."* – jww Feb 13 '18 at 11:04

1 Answers1

0

try to use pkcs5padding on value before encrypt. i.e.

remember the blocksize should be 8-byte based, i.e. 8/16/24 etc.

function pkcs5_pad($text, $blocksize)
{
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr(0), $pad);
}

and encrypt option should be OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, i.e.

openssl_encrypt(pkcs5_pad($value, 16), 'aes-256-ecb', $aes_key, 3, '')
buaacss
  • 757
  • 6
  • 10
  • ecb is not recommended, it seperates text into segments and encrypt each of them without any context info, which is "quite easy" to decrypt compare to cbc mode. – buaacss Nov 02 '20 at 08:55