【问题标题】:Hash a password and save it and the salt to mysql pdo utf8 encoding散列密码并将其和盐保存到 mysql pdo utf8 编码
【发布时间】:2023-04-06 00:52:01
【问题描述】:

我有这个问题,如果不合适,请在 cmets 中告诉我,我会放弃它。事情是这样的: 我用这段代码生成盐:

$salt = mcrypt_create_iv(32);

密码是这样的:

$password =  hash('sha256', $_POST['password'] . $salt);

并将$salt和$password保存到MYSQL数据库中,目前没有问题,如果我这样连接:

$pdo = new PDO(
    'mysql:host=hostname;dbname=defaultDbName',
    'username',
    'password'
);

但如果我以其他方式连接:

$pdo = new PDO(
    'mysql:host=hostname;dbname=defaultDbName;charset=utf8',
    'username',
    'password'
);

盐没有保存到数据库中或以错误的值和长度保存;除非我这样做: $salt = utf8_encode(mcrypt_create_iv(32);); 但我认为这是不对的,我的意思是为什么我应该编码, mcrypt_create_iv(32) 和 utf-8 有什么问题?

【问题讨论】:

  • 您的 IV 将基本上是“随机”的二进制垃圾。如果您将其放入 text/varchar 字段,它将受该字段的字符集翻译规则的约束。二进制数据应该进入 varbinary/blob 字段。这些都没有字符集,你投入的领域将是它的结果。
  • 因此,将字段的提示更改为 blob 将使其与连接的字符集无关,这就是您的意思
  • 这就是二进制/blob 字段的意义所在。由于翻译规则的应用不正确,因此没有字符集随机丢弃数据,而这些规则一开始就不应该应用于数据。

标签: php mysql utf-8 pdo


【解决方案1】:

您的解决方案将起作用:

mcrypt_create_iv 返回一堆字节,它们方便地放在一个字符串中。但是因为它们可以有任何值,所以它们可能会导致错误的 UTF-8 序列。 utf8_encode 解决了这个问题,只要您在从数据库中读回 utf8_decode 后还记得使用它,它就会正常工作。

如果您的连接不是 utf8,那么每个字节都将被视为单个(整个)ANSI 字符,您不需要对其进行任何编码。

最佳解决方案:保持二进制:

由于此数据实际上是二进制数据,而不是真正的字符串,因此二进制字段(BINARY、VARBINARY 或 BLOB)将是存储它的更好选择,以防止因编码或解码而出现任何问题。

BINARY 可能是最好的选择,因为这个数据的长度既不可变,也不大。

http://dev.mysql.com/doc/refman/5.0/en/binary-varbinary.html

替代方案:存储为实际文本,没有花哨的字符:

另一种解决方案是使用bin2hex 将二进制数据转换为十六进制表示。该字符串的长度是原来的两倍,但它只包含字母和数字,并且可以安全地用于任何类型的字符串字段。您可以使用hex2bin 将其转换回来。

【讨论】:

  • 好的,谢谢,我现在明白了,另外我想问一下,使用 utf-8 编码是否存在安全问题?
  • 可能有。我会选择将此信息以其原始二进制格式保存在 BINARY 字段中。
【解决方案2】:

正如其他海报所提到的,mcrypt_create_iv 可以生成不适合 utf8 的字符。试试这样的:

function generate_random($length=16, $simple=false){
        $result='';
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()+=-_?~';
        if($simple)
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
        for ($i = 0; $i < $length; $i++)
            $result .= $chars[mt_rand(0, strlen($chars)-1)];
        return $result;
    }

16 个字符和 78 个字符集产生 1.877 * 10^30 个组合。对于像 sha256 这样的单向哈希,加上密码长度应该绰绰有余。

【讨论】:

  • 谢谢你的回答,好像是自己动手做的,不带括号的编码方式怎么称呼?
猜你喜欢
  • 2014-06-10
  • 2013-10-15
  • 2015-02-17
  • 2015-08-20
  • 1970-01-01
  • 2015-04-12
  • 2011-06-02
  • 2011-10-29
相关资源
最近更新 更多