The mcrypt-extension is deprecated will be removed in PHP 7.2 according to the comment posted here. So I am looking for an alternative way to encrypt passwords.
Right now I am using something like
mcrypt_encrypt(MCRYPT_RIJNDAEL_128, md5($key, true), $string, MCRYPT_MODE_CBC, $iv)
I need your opinion for the best/strongest way to encrypt passwords, the encrypted password should of course supported by PHP 7.xx and should also be decryptable because my customers do want to have an option to 'recover' their passwords without generating a new one.
You should use
openssl_encrypt()
function.You should use OpenSSL over
mcrypt
as it's actively developed and maintained. It provides better security, maintainability and portability. Secondly it performs AES encryption/decryption much faster. It uses PKCS7 padding by default, but you can specifyOPENSSL_ZERO_PADDING
if you need it. To use with a 32-byte binary key, you can specifyaes-256-cbc
which is much obvious thanMCRYPT_RIJNDAEL_128
.Here is the code example using Mcrypt:
And here is the version written using OpenSSL:
Source: If You're Typing the Word MCRYPT Into Your PHP Code, You're Doing It Wrong.
As suggested by @rqLizard, you can use
openssl_encrypt
/openssl_decrypt
PHP functions instead which provides a much better alternative to implement AES (The Advanced Encryption Standard) also known as Rijndael encryption.As per the following Scott's comment at php.net:
Further reading:
Code examples
Example #1
Example #2
Example #3
Based on above examples, I've changed the following code which aims at encrypting user's session id:
into:
To clarify, above change is not a true conversion since the two encryption uses a different block size and a different encrypted data. Additionally, the default padding is different,
MCRYPT_RIJNDAEL
only supports non-standard null padding. @zaphAdditional notes (from the @zaph's comments):
MCRYPT_RIJNDAEL_128
) is equivalent to AES, however Rijndael 256 (MCRYPT_RIJNDAEL_256
) is not AES-256 as the 256 specifies a block size of 256-bits, whereas AES has only one block size: 128-bits. So basically Rijndael with a block size of 256-bits (MCRYPT_RIJNDAEL_256
) has been mistakenly named due to the choices by the mcrypt developers. @zaphEncryption with different block sizes for Rijndael produces different encrypted data.
For example,
MCRYPT_RIJNDAEL_256
(not equivalent toAES-256
) defines a different variant of the Rijndael block cipher with size of 256-bits and a key size based on the passed in key, whereaes-256-cbc
is Rijndael with a block size of 128-bits with a key size of 256-bits. Therefore they're using different block sizes which produces entirely different encrypted data as mcrypt uses the number to specify the block size, where OpenSSL used the number to specify the key size (AES only has one block size of 128-bits). So basically AES is Rijndael with a block size of 128-bits and key sizes of 128, 192 and 256 bits. Therefore it's better to use AES, which is called Rijndael 128 in OpenSSL.