First off, MD5 is not a secure way to store passwords. Take a look at the password_hash function and bcrypt for a more modern and secure solution. See also: How do you use bcrypt for hashing passwords in PHP?
As for the IMAP password, you do not need hashing as those are "one-way". You need an encryption algorithm.
One of the better options is to use openssl_encrypt()
and a secure key stored on the server. This is the approach Laravel takes for example.
Take a look at this as an example: https://github.com/laravel/framework/blob/5.2/src/Illuminate/Encryption/Encrypter.php#L62
/**
* Encrypt the given value.
*
* @param string $value
* @return string
*
* @throws \Illuminate\Contracts\Encryption\EncryptException
*/
public function encrypt($value)
{
$iv = random_bytes($this->getIvSize());
$value = \openssl_encrypt(serialize($value), $this->cipher, $this->key, 0, $iv);
if ($value === false) {
throw new EncryptException('Could not encrypt the data.');
}
// Once we have the encrypted value we will go ahead base64_encode the input
// vector and create the MAC for the encrypted value so we can verify its
// authenticity. Then, we'll JSON encode the data in a "payload" array.
$mac = $this->hash($iv = base64_encode($iv), $value);
$json = json_encode(compact('iv', 'value', 'mac'));
if (! is_string($json)) {
throw new EncryptException('Could not encrypt the data.');
}
return base64_encode($json);
}
/**
* Decrypt the given value.
*
* @param string $payload
* @return string
*
* @throws \Illuminate\Contracts\Encryption\DecryptException
*/
public function decrypt($payload)
{
$payload = $this->getJsonPayload($payload);
$iv = base64_decode($payload['iv']);
$decrypted = \openssl_decrypt($payload['value'], $this->cipher, $this->key, 0, $iv);
if ($decrypted === false) {
throw new DecryptException('Could not decrypt the data.');
}
return unserialize($decrypted);
}
/**
* Get the IV size for the cipher.
*
* @return int
*/
protected function getIvSize()
{
return 16;
}
Obviously, that Laravel code relies on other parts of Laravel, but as an example, this is sufficient. Once you have the encrypted value, you can store it in your database.
Remember security is only as strong as the weakest link -- so make sure your database credentials are secure and your database user has the minimum amount of permissions for your application to function.