我的数据库在MD5中存储用户的登录密码,因此当他们登录时,会将他们输入的密码转换为MD5与数据库中的MD5密码进行比较。
我正在实施应用程序可以使用IMAP连接到其电子邮件帐户的功能。所以我需要将用户的电子邮件帐户密码存储在数据库中,但据我所知,我不能使用MD5,因为我需要将他们的密码最终作为纯文本输入用于通过IMAP连接进行连接。
将密码安全地存储在数据库中,但能够检索并将其转换为脚本中的纯文本的解决方案是什么?
答案 0 :(得分:0)
首先,MD5不是存储密码的安全方式。请查看password_hash功能和 bcrypt ,以获得更现代,更安全的解决方案。另见:How do you use bcrypt for hashing passwords in PHP?
对于IMAP密码,不需要散列,因为它们是单向"。您需要加密算法。
更好的选择之一是使用openssl_encrypt()
和存储在服务器上的安全密钥。这就是Laravel采用的方法。
以此为例: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;
}
显然,Laravel代码依赖于Laravel的其他部分,但作为一个例子,这就足够了。获得加密值后,可以将其存储在数据库中。
记住安全性与最薄弱的链接一样强 - 所以请确保您的数据库凭据是安全的,并且您的数据库用户拥有应用程序运行的最小权限。