整个密码列的mysql sha1加密

时间:2014-02-25 00:42:55

标签: php mysql sha1

我在phpmyadmin中有一个包含用户名和密码的表,但密码字段未加密。我想将密码字段的整列加密为SHA1格式。知道怎么做吗?

5 个答案:

答案 0 :(得分:2)

首先,请阅读How to securely hash passwords?

然后,您可以查找要使用的PHP PBKDF2,Bcrypt或Scrypt实现。

在数据库中,您需要:

  • 盐的列 - 也许是BINARY(16)的128位盐。请参阅What is the correct way to make a password salt? - Adnan的答案特别包括PHP函数,但如果使用bin2hex,则需要一个包含32个十六进制字符的CHAR(32)列(与16个二进制字节相同)。
  • 迭代计数列(工作因子)。 INT UNSIGNED应该工作。
    • 如果您坚持一次迭代(即sha1(密码)),则不再需要这样做,但您没有使用安全密码存储机制。不要那样做。
    • 可以对此进行硬编码,但之后很难再增加它。使用列,您可以在数据库中拥有许多不同的迭代计数/工作因子,并在用户登录时透明地增加它们。
    • 对于PBKDF2,开始数以万计并开始工作。对于所有这些,请增加到低于您将受到投诉的地方/受到预期增长的CPU限制。购买新硬件时增加。
  • 结果哈希本身的列。
    • 对于PBKDF2-HMAC-SHA-1,BINARY(20)是SHA-1的原生大小
    • 对于PBKDF2-HMAC-SHA-512,BINARY(64)是SHA-512的原生大小。
      • BINARY(20)仍然优于PBKDF2-HMAC-SHA-1中的20个,因为SHA-512需要64位操作,这些操作目前会降低攻击者GPU对CPU的优势。
    • 或者,对于任何这些CHAR(BINARY存储大小的两倍)和bin2hex
    • 永远不要将PBKDF2的输出大小用于大于本机散列大小(如上所列),否则它是防御者的免费奖励。
  • 可选:用于保护您正在使用的密码“版本”的列,以便您稍后可以轻松升级到其他版本。 TINYINT UNSIGNED在这里应该运作良好。

如果您真的喜欢(并且不推荐),您可以创建类似PBKDF2的MySQL实现,并且由于MySQL 5.5.5及更高版本具有SHA-512 function,您可以也许使用MS SQL Server PBKDF2-HMAC-SHA-512 impelmentation作为示例,但绝对要确保对known test vectors进行验证。

答案 1 :(得分:0)

update mytable set password=sha1(password)

您至少应该验证列定义是否能容纳40个字符,否则可能会使情况恶化。

我希望您知道,从那时起,您还应该重写代码以在发送和/或与DB进行比较之前加密密码。

答案 2 :(得分:0)

答案 3 :(得分:0)

此时甚至不单独使用SHA-1哈希,它本身不够安全。

请参阅OWASP的Password Storage Cheat Sheet。除了为每个用户使用唯一的盐盐密码外,您应该使用更强大的加密功能。

如果你有PHP 5.5,你可以使用PHP的password_hash()函数使用bcrypt算法,或者如果你没有PHP 5.5,你可以使用ircmaxell的PHP implementation

如果此时只使用SHA-1,您甚至可能不会打扰,因为数据库中的大多数密码可能已经在SHA-1彩虹表中了。

要更新数据库,请编写一个简短的PHP脚本以从数据库中读取每个密码,应用散列函数,然后使用新的散列密码更新该行。然后修改您的寄存器和登录函数,以便在将输入的密码与存储在数据库中的密码进行比较时使用新的哈希函数。

答案 4 :(得分:0)

对于今天的安全标准,我会这样做:

  1. 向表中添加4个字段(Hash,Salt,Iteration,Algo)
  2. 使用crackstation中的此代码来哈希并验证您的密码
  3. 用法非常简单:

    $plain_password="messi";
    
    $hash=create_hash($plain_password);
    

    $ hash是一个包含您需要保存到数据库的所有数据的数组

    array(4) {
      [0]=>
      string(6) "sha256"
      [1]=>
      string(4) "1000"
      [2]=>
      string(32) "wJnwu2uA4rVdW8Momz3CgS8W7MdEmaLH"
      [3]=>
      string(32) "0g2b0ZrpnObAx6z1L/8g8PPNbTG+92BI"
    }
    

    将其保存到数据库,下次必须将这些值检索为:

    SELECT 
    CONCAT(password_algo, ":" ,password_iteration,":" , password_salt,":" , password_hash)
    FROM users WHERE userEmail='messi@argentina.com';
    

    在验证函数中使用字符串结果

    validate_password($password_to_validate, $stored_hash_from_db)
    

    如果有效,您将获得True,否则为False。