代码之家  ›  专栏  ›  技术社区  ›  Tarik

用PHP和MySQL编写hash

  •  10
  • Tarik  · 技术社区  · 16 年前

    尤其地 对每个密码使用唯一的salt,同时在单个列中保留salt+密码。

    我从PHP手册中找到了所有这些很酷的方法来加密密码(SHA-256,但是MySQL只支持SHA/1和MD5吗?)和其他东西,但是不确定如何存储和检索密码。

    SHA('$salt'.'$password') // My query sends the password and salt 
                             // (Should the $salt be a hash itself?)
    

    从那以后我就迷路了。

    不用盐就能找回密码很容易,但是盐把我弄糊涂了。我又从哪里得到$salt的价值呢,特别是如果它是唯一的和安全的呢?我是否将它们隐藏在另一个数据库中?常量(似乎不安全)?

    编辑: HMAC中的关键变量应该是salt还是其他变量?

    3 回复  |  直到 16 年前
        1
  •  5
  •   igorw    16 年前

    首先,您的DBMS(MySQL)不需要对加密散列有任何支持。您可以在PHP端完成所有这些,这也是您应该做的。

    // the plaintext password
    $password = (string) $_GET['password'];
    
    // you'll want better RNG in reality
    // make sure number is 4 chars long
    $salt = str_pad((string) rand(1, 1000), 4, '0', STR_PAD_LEFT);
    
    // you may want to use more measures here too
    // concatenate hash with salt
    $user_password = sha512($password . $salt) . $salt;
    

    现在,如果要验证密码,请执行以下操作:

    // the plaintext password
    $password = (string) $_GET['password'];
    
    // the hash from the db
    $user_password = $row['user_password'];
    
    // extract the salt
    // just cut off the last 4 chars
    $salt = substr($user_password, -4);
    $hash = substr($user_password, 0, -4);
    
    // verify
    if (sha512($password . $salt) == $hash) {
      echo 'match';
    }
    

    你可能想看看 phpass ,它也使用这种技术。这是一个PHP散列解决方案,它使用盐渍和其他一些东西。

        2
  •  0
  •   Kelly Copley    16 年前

    我的方法是在数据库配置文件中创建一个函数,返回一个键字符串。配置文件应该在您的站点根目录之外,以便Web服务器可以访问该文件,但不能访问其他文件。例如:

    function enc_key(){
         return "aXfDs0DgssATa023GSEpxV";
    }
    

    然后在您的脚本中,将其与MySQL中的sql查询、AES\ U ENCRYPT和AES\ U DECRYPT函数一起使用,如下所示:

    require_once('dbconf.inc.php');
    
    $key = enc_key();
    
    //When creating a new user
    $sql = "INSERT INTO users (username, password) VALUES ('bob', AES_ENCRYPT('{$key}', {$password}))";
    
    //When retrieving users password
    $sql = "SELECT AES_DECRYPT('{$key}', password) AS password FROM users WHERE username like 'bob'";