如何在MySQL中安全地存储密码并对外部服务进行身份验证

时间:2014-08-14 16:01:00

标签: php mysql

目前我有一个PHP脚本通过IMAP连接到邮件服务器并将新电子邮件解析到MySQL。连接到邮件服务器的凭据使用纯文本存储在MySQL中,有没有办法可以加密存储在MySQL中的密码?

4 个答案:

答案 0 :(得分:2)

MySQL支持AES_ENCRYPT()功能。您可以在将其插入数据库时​​进行加密,并在选择退出时对其进行解密。

阅读我链接的文档以获取示例。

然后确保在使用明文密码imap_open()时使用端口993进行与IMAP服务器的TLS加密连接。

答案 1 :(得分:1)

取决于电子邮件服务器需要进行身份验证的内容。如果密码需要使用纯文本发送(可能是因为电子邮件服务器自身散列),您应该加密密码,然后在将密码发送到电子邮件服务器之前对其进行解密。

如果您可以向服务器发送散列密码,请使用散列函数(md5,sha1,sha512,...)对其进行散列。

hash('sha1', $password);
sha1($password); // Same result as above.

如果您必须加密(为了能够解密),您可以使用mcrypt或openssl。

http://php.net/manual/en/function.mcrypt-encrypt.php http://php.net//manual/en/function.openssl-encrypt.php

这里的区别在于散列密码不能取消哈希。加密密码可以解密。

答案 2 :(得分:0)

散列密码的重点是确保在数据库被黑客入侵的情况下最终用户的隐私和机密性。显然你不能使用哈希函数,因为你的脚本需要回读imap密码,所以你应该用一些对称的crypt函数加密它(例如AES,河豚,3DES等)。现在你面临着存储对称密钥材料的问题:将它存储在同一个数据库中是完全愚蠢的“因为黑客攻击数据库意味着要读取密钥。您可以对脚本内部或外部txt文件中的密钥材料进行硬编码:现在,黑客应该同时破坏mysql服务器和Web域以检索imap密码,这是使用标准php +可以达到的最高安全级别mysql通用域。

答案 3 :(得分:0)

我使用这些功能或其中的一些变体进行登录。它往往非常安全,因为它会对密码加密并对它们进行哈希处理。

<?php
function password_encrypt($password) {
        // Tells PHP to use Blowfish with a "cost" of 10
        $hash_format = "$2y$10$";
        // Blowfish salts should be 22-characters or more
        $salt_length = 22;
        $salt = generate_salt($salt_length);
        $format_and_salt = $hash_format . $salt;
        $hash = crypt($password, $format_and_salt);
        return $hash;
    }

    function generate_salt($length) {
        // Not 100% unique, not 100% random, but good enough for a salt
        // MD5 returns 32 characters
        $unique_random_string = md5(uniqid(mt_rand(), true));

        // Valid characters for a salt are [a-zA-Z0-9./]
        $base64_string = base64_encode($unique_random_string);

        // But not '+' which is valid in base64 encoding
        $modified_base64_string = str_replace('+', '.', $base64_string);

        // Truncate string to the correct length
        $salt = substr($modified_base64_string, 0, $length);

        return $salt;
    }

    function password_check($password, $existing_hash) {
        // existing hash contains format and salt at start
        $hash = crypt($password, $existing_hash);
        if ($hash === $existing_hash) {
        return true;
        } else {
        return false;
        }
    }

    function attempt_login($username, $password) {
        $admin = find_admin_by_username($username);
        if ($admin) {
            // found admin, now check password
            if (password_check($password, $admin["hashed_password"])) {
                // password matches
                return $admin;
            } else {
                // password does not match
                return false;
            }
        } else {
            // admin not found
            return false;
        }
    }
?>
相关问题