用户内容网站的mysql密码存储

时间:2010-11-03 06:04:39

标签: mysql hash passwords sha

要存储用户密码,我将使用SHA 256 + salting。只是想确认这些是否正确。业务要求是密码应该是最少8个输入和最多32个输入。 (任何输入除空格外都有效)

为了满足这些要求,计划是:
前端 - 验证最大输入为32&最小输入8。

后端数据库(MySQL)架构将是:
pass_hash(64)CHAR - 存储密码哈希
pass_slt(32)VARCHAR - 为每个用户存储唯一的盐

对于腌制,我不确定使用什么价值。但我想当用户创建一个帐户时,我会为每个用户创建一个随机字符并使用它。然后另一个问题是:我将盐存储为纯文本还是需要哈希/加密?

此外,我不知道它是否重要,但密码可以支持多语言与当前的计划,还是我会遇到任何问题? (我说的是阿拉伯语,中文等时髦的人物)

2 个答案:

答案 0 :(得分:1)

关于盐:

盐是公共数据(如果它是保密的,那么它不会被称为“盐”而是“关键”)。必须知道salt验证密码(因为它与密码一起进入散列函数),因此它会像你想要的那样以明文形式存储。

盐的目的是防止攻击者在攻击实例之间共享攻击成本。通常可以猜测用户选择的密码(用户只有人脑,很少善于记忆复杂的密码)。盐确保至少攻击者必须为每个攻击密码支付密码猜测的全价(即“尝试”可能密码的大词典)。

只要每个密码都是唯一的,盐就可以正常工作。请注意,每个用户的唯一性是不够的:有时,用户更改其密码,并且您不希望将相同的盐用于下一个密码(否则,某些级别的成本共享可用于攻击者)。因此,您希望在存储密码时选择新的盐,即每当密码更改时创建帐户

使用足够大的随机盐可以很容易地确保盐的独特性。 32字节的盐就足够了:选择两次相同的盐(运气不好)的风险可以忽略不计。

除了腌制之外,额外的安全级别是使密码散列“昂贵”。例如,当您对(盐渍)密码进行哈希处理时,实际上会对salt +密码序列的10000次串联进行哈希处理。对于您和攻击者而言,这使得密码验证成本高出10000倍。通常情况下,合法的密码验证可以在计算上更重,没有明显的影响(即使您每秒检查100个用户密码,您仍然可以投入100μs,并且它将仅使用1%的处理时间),但是为攻击者制造10000倍的东西是一个好主意。

语言:

非ASCII密码的主要问题是某些字形可能会使用多种编码。例如,'é'可以用Unicode编码,作为单个代码点(U + 00E9 LATIN SMALL LETTER E WITH ACUTE)或两个代码点(U + 0065 LATIN SMALL LETTER E,然后是U + 0301 COMBINING ACUTE ACCENT)。请注意,此示例是关于一个相当普通的法语字母,没有像中文或韩文那样花哨(计算机方面)。编码问题可以通过Unicode Normalization Forms来处理,但这不是一个简单的编程任务。一些编程环境可以提供帮助(例如,在Java中,使用实现UNF的java.text.Normalizer。)

此外,对于切换键盘的用户,例如非ASCII密码很难输入。当用户想要在酒店或机场使用共享计算机时(在这样的系统上输入敏感密码无论如何都不是一个好主意)。

如果可能的话,我建议尝试强制使用仅ASCII密码,否则会咬紧牙关:执行UNF(使用NFD格式),然后执行UTF-8编码。产生的字节序列将进入散列阶段。

答案 1 :(得分:-1)

看起来是正确的,除了盐应该是固定长度(例如总是32字节);你是正确的,它应该是随机的和每个用户。我认为加密盐没有任何实际好处。当攻击者已经拥有您的数据库的明文版本时,Salts会抵御这种情况。

就多语言而言,你应该对你在应用程序中使用的字符编码以及你正在调用SHA-256的完全的内容保持一致。