【问题标题】:Comparing accuracy for password and username: utf8_general_ci or utf8_bin?比较密码和用户名的准确性:utf8_general_ci 还是 utf8_bin?
【发布时间】:2011-06-14 15:36:47
【问题描述】:

我在这里读过一篇文章,utf8_bin 可以让我们更准确地比较字符,而 utf8_general_ci 则不能。

我想知道 - 我是否有一个存储用户名和密码的表,并且当用户登录我的网站时,我需要它们准确或正确。

那么我应该为此使用 utf8_bin 吗?

谢谢。

编辑:

顺便说一下,这是我用来有密码的哈希函数,

function hash_sha512($phrase,&$salt = null)
{
    //$pepper = '!@#$%^&*()_+=-{}][;";/?<>.,';

    if ($salt == '')
    {
        $salt = substr(hash('sha512',uniqid(rand(), true).PEPPER_KEY.microtime()), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return hash('sha512',$salt.PEPPER_KEY.$phrase);
}

【问题讨论】:

  • 您应该将密码存储为加盐哈希。奖励:有了哈希,你不必担心 unicode(仅 [a-f0-9])
  • @knittl:是的,我已经散列了我所有的密码。谢谢。
  • @lauthiamkok:散列值有什么格式?
  • @knittl:在一个租用廉价 AWS 实例来构建快速彩虹表​​的世界里,sha1() 的加盐哈希对你没有多大好处。 sha1() 算法太快了。
  • @andrew:总比不加盐或不散列好……

标签: mysql database-design collation password-protection


【解决方案1】:

您说的是排序规则——它是 MySQL 表将支持的字符。排序规则上的“_ci”表示排序规则不区分大小写。意思是,“a”==“A”,而在区分大小写的排序规则中,示例将评估为假。

所以是的,选择区分大小写的排序规则将提供更好的准确性。您可以使用不区分大小写的排序规则存储值,但使用 COLLATE function 为查询评估设置一个特定的排序规则。

【讨论】:

    【解决方案2】:

    首先是关于密码存储的问题...因为您似乎正在使用 PHP(从您的问题历史记录中)... Salted sha1() 哈希在租用几个 AWS 实例的世界中不会削减它计算快速彩虹表​​...sha1() 太快了。

    与其尝试自己动手做密码学,为什么不相信由该领域的实际专家制作的库呢?使用Portable PHP password hashing framework

    PHPass 实际上使用了 bcrypt,这是一种旨在防止彩虹表、字典和暴力破解攻击的算法。您可以使用多轮对其进行初始化:轮数越高,计算散列所需的时间就越长。这样,如果处理能力提高,您可以创建更强大的哈希。

    使用很简单:

    require('PasswordHash.php');
    
    $phpass = new PasswordHash(12, false); // Initiate for 12 rounds, using bcrypt
    
    // Hash a password
    $hash = $phpass->HashPassword('my secret password');
    
    // Compare an hash to a given password
    $formSupplied = 'hello world';
    $isRight = $phpass->CheckPassword($formSupplied, $hash);
    
    if($isRight) echo "Good";
    else echo "Wrong";
    

    现在关于用户名...使用_bin 排序规则存储它们(即:utf8_bin)。这将强制 MySQL 在WHERE 期间进行二进制比较,并有效地使您的用户名区分大小写。

    但是,由于这是 UTF-8,因此在插入和查询数据之前规范化用户名非常重要。不同的操作系统以不同的方式表示重音字符。 PHP 有 intl 扩展,它有一个 UTF-8 规范化的工具。应该这样做:

    $_POST['username'] = Normalizer::normalize($_POST['username']);
    

    【讨论】:

    • 没有 utf8 说明任何字符都应该只有一种有效编码吗?
    • @knittl: é é... 相同的字符,两种不同的书写方式... 有些字符可以通过其规范化形式或通过其基本形式加上变音符号来表示。见UAX #15: Unicode Normalization Forms
    • @Andrew Moore:感谢您的回复。我可以问 - 在这里“正常化”是什么意思?为什么我们需要规范化用户名?
    • @Andrew Moore:是的,我正在使用 PHP... :-)
    • @andrew:这两个角色在我的屏幕上看起来不同,但我理解你的意思。使用单个字符与将字符与其重音组合起来。感谢澄清
    猜你喜欢
    • 2013-08-24
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多