2010-04-07 66 views
5

我已经创建了一个盐; MD5(兰特(0,10000000)); (可能有更好的方法吗?)MySQL和php中的唯一文本字段

似乎没有可能使文本字段在MYSQL中是唯一的。那么如何检查盐是否已经用于以前的用户?

或者我应该根据当前的日期/时间生成盐?因为2个用户不可能完全同时注册正确吗?

+1

您可以在varchar字段上添加唯一约束 - 您可以使用它来检查重复的盐。 – thetaiko 2010-04-07 17:04:54

回答

1

对于盐来说,唯一性比长度和可预测性更重要。你认为攻击者有盐。

通用唯一标识符(UUID)将是最好的,并且有一些示例可在文档页面上为php uniqueid()函数生成通用唯一标识符。 UUID优于随机字符串,因为它具有人类可读性和固定长度,因此您可以将其存储在varchar字段中,并使用唯一索引来确保没有重复。

使用MD5散列时间是生成唯一值的常用方法,因为它具有固定长度并且是人类可读的。然而,更有意义的是生成一个固定长度的随机字符串并将其编码为十六进制。哈希不是为了唯一性而设计的,因为它们被设计为不可逆。使用散列函数保证了冲突,尽管与MD5的冲突少于MD5。

盐的长度真的只是一个因素,因为盐越长,越有可能是普遍独特的。

+0

应该是一些怪胎巧合2发生有相同的盐的用户决定有相同的密码,然后 – 2010-04-07 18:07:05

+0

@乔纳森,如果有重复的盐与不同的密码摘要,我会先攻击这些帐户,因为它给了我一个更好的机会找到一个成功的碰撞。两个具有相同密码和密码的帐户会给攻击者两个价格相同的攻击者,但攻击者不会有任何中断。 – 2010-04-07 18:18:59

0

md5()是一个破碎的算法,不应该被触及。

rand()因为它基于系统时钟而略有中断。

更好的方法是:

function generateRandomKey() 
{ 
    return base_convert(uniqid(mt_rand(), true), 16, 36); 
} 

编辑:如果有更好的方法或我错了,请告诉我你做这件事的方式。我真的很感兴趣,并想知道我是否不安全。

+1

对于另一个更广泛接受的观点,请参阅http://stackoverflow.com/questions/2329609/is-it-safe-to-store-passwords-hashed-with-md5cryptoserviceprovider-in-c – dkretz 2010-04-07 16:56:28

+0

@ledorifier,您发布的链接是关于散列密码,不生成随机盐。 – 2010-04-07 17:05:31

+1

和http://stackoverflow.com/questions/157998/whats-the-difference-between-sha-and-md5-in-php。我指的是“......从未被触动过”。 – dkretz 2010-04-07 17:07:19

0

使用用户ID和日期时间与SHA1生成盐。

1

MySQL的索引在文本字段上是长度受限的,它们不会像在char/varchar字段中那样自动进入全字段,所以没有实际的方法在文本字段上使用“唯一”键。

但如果你存储由MySQL生成的哈希值,那么你不需要文本 - 在有结果是纯文本,所以只使用固定长度的字符字段:

mysql> select length(md5('a')), length(sha1('a')); 
+------------------+-------------------+ 
| length(md5('a')) | length(sha1('a')) | 
+------------------+-------------------+ 
|    32 |    40 | 
+------------------+-------------------+ 

,然后你可以对该字段应用一个唯一的约束。

0

你通常不会经常产生盐串。所以当你第一次产生它们时,你应该做得很好。更长和更随机的字符串更好。新密码

update user set salt = :salt, password = sha1(concat(:password, :salt)) where id = :id limit 1; 

function generateSalt($length = null) 
{ 
    if (!is_int($length) || ($length < 1)) $length = 250; 
    do { 
    $salt[] = chr(mt_rand(0, 255)); 
    } while (--$length); 
    return implode('', $salt); 
} 

更新查询,你可以检查密码是否正确,并在同一时间获得用户数据。

select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;