【问题标题】:How can I store password securely in MySQL and authenticate to external services如何在 MySQL 中安全地存储密码并对外部服务进行身份验证
【发布时间】:2014-08-14 16:01:00
【问题描述】:

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

【问题讨论】:

  • 由于您连接到外部资源,您需要加密密码而不是散列密码。散列密码使您无法取回纯文本密码。

标签: php mysql


【解决方案1】:

MySQL 支持AES_ENCRYPT() 函数。您可以在将其 INSERT 到数据库时进行加密,并在 SELECT 退出时对其进行解密。

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

然后,当您使用明文密码进行 imap_open() 时,请确保使用端口 993 与 IMAP 服务器建立 TLS 加密连接。

【讨论】:

  • 感谢您的评论。我尝试了这种方法,使用这样的方法: $key = 'ASKSDFNSDFKEISDJHAHDLDSDF1235UUUiidfsdf'; $pass = $VAR['email_account_password']; $hash = AES_ENCRYPT('$pass', '$key');我在控制台中没有收到任何错误,但它不起作用。有什么建议吗?
  • 看起来你在单引号中有 PHP 变量。这不会扩展 PHP 变量,它们保留为带有美元符号的字符串。
【解决方案2】:

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

如果您可以向服务器发送散列密码,请使用散列函数(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

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

【讨论】:

  • md5 和 sha1 应该避免。应使用 SHA2 或更高版本(sha512 是 SHA2 的一部分)
  • 如果您的 PHP >= 5.5 可用,请使用 password_hash php.net/manual/en/function.password-hash.php
  • 不要提及 md5、sha1 或任何其他 加密 算法。这些不是正确的哈希。即使是为了举例。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    <?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;
            }
        }
    ?>
    

    【讨论】:

      猜你喜欢
      • 2012-09-13
      • 2012-11-09
      • 2021-07-26
      • 2017-01-29
      • 2020-07-20
      • 2023-03-21
      • 1970-01-01
      • 2012-10-29
      • 2020-10-27
      相关资源
      最近更新 更多