如何在我的登录密码中实现salt? [英] How do I implement salt into my login for passwords?

查看:208
本文介绍了如何在我的登录密码中实现salt?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的登录系统中实现一个salt,但是对于这个工作原理有点困惑。我无法理解它背后的逻辑。我知道md5是一种单向算法,我所遇到的所有功能似乎都将所有内容混合在一起。如果是这种情况,如何将密码取回来进行比较?我最大的问题是,如何腌制用户的密码比仅仅对密码进行哈希处理更安全?如果一个数据库曾经被破解过,那么散列和salt一起存在于数据库中。这不就是黑客需要的吗?



我还在另一个帖子里发现了另一个开发人员说的话:


确保您的salt和算法与$ 数据库分开存储


我想将salt存储在数据库中。这真的是一个问题吗?



我正在寻求一些帮助来理解这是如何工作的,以及最佳做法是什么。任何帮助非常感谢。






编辑:
我想感谢大家的回应和想法。尽管我现在可能更困惑,但对我来说,这确实是一种学习体验。再次感谢大家。

解决方案

散列函数总是为相同的输入字符串返回相同的值。假设我的用户(Alice)拥有密码 secret 。散列秘密使用 md5() 导致以下散列:

  5ebe2294ecd0e0f08eab7690d2a6ee69 

攻击者(Mallory)可以使用字典(常见单词和密码列表)或提供该服务的各种网站之一轻松找到当他在他的字典中看到 5ebe2294ecd0e0f08eab7690d2a6ee69 = secret 时,密码是秘密的。



<在不知道盐的情况下使用字典攻击就更困难。考虑以下几点:

 <?php 
$ salt ='@!#%$ @#$ @ SADLkwod ,sdaDwqksjaoidjwq @#@!;
$ hash = md5($ salt。'secret');

结果散列值现在 b58ad809eece17322de5024d79299f8a ,但Alice密码仍然是秘密。现在,如果马洛里掌握了盐腌散列,她很可能在她的字典中找不到答案。如果她这样做,字典会给她错误的答案。



不要在数据库中存储静态盐。最好将它与应用程序的配置一起存储(顺便说一下,不应该从网络上获得)。



如果你要使用动态盐,你将要需要使用数据库。使用现有有效数据的非空列来构建您的salt(基于密钥加密密钥的blowfish加密的用户名字符串通常具有密码安全性)。不要使用单独的盐柱。如果你不能使用现有的列,请将你的salt与你的哈希列在同一列。例如,使用128位salt的前32个字符,然后使用160位散列的最后40个字符。下面的函数会生成这样一个哈希:

pre $函数seeded_sha1($ string,$ seed_bits){
if(( $ seed_bits%8)!= 0){
抛出新的异常('位必须被8整除);
}

$ salt ='';
for($ i = 0; $ i <$ seed_bits; $ i + = 8){
$ salt。= pack('c',mt_rand());
}

$ hexsalt = unpack('h * hex',$ salt);

返回$ hexsalt ['hex']。 sha1($ salt。$ string);


函数compare_seeded_sha1($ plain,$ hash){
$ sha1 = substr($ hash,-40);
$ salt = pack('h *',substr($ hash,0,-40));

$ plain_hash = sha1($ salt。$ plain);
return($ plain_hash == $ sha1);



$ b如果攻击者使用SQL注入攻击你的数据库,至少哈希值是/她检索将不会有用,因为他/她将无法访问您的应用程序配置。如果您的服务器获得了root权限,则无论您做什么,都可以进行相当程度的游戏。



注意:还可能存在其他类型的攻击 md5() 这就是为什么你使用更安全的哈希算法,例如 sha1() 。或者,更好的办法是使用便携式PHP密码散列框架,该框架的设计注重安全性并向后兼容几乎任何PHP版本。

  require('PasswordHash.php'); 

$ pwdHasher = new PasswordHash(8,FALSE);

// $ hash是你要存入数据库的内容
$ hash = $ pwdHasher-> HashPassword($ password);

// $ hash将是存储在你的数据库中的用户$ hash。
if($ checked){
echo'password correct';
} else {
echo'错误凭证';
}


I want to implement a salt into my login system but am a bit confused on how this is supposed to work. I can't understand the logic behind it. I understand md5 is a one-way algorithm and all of the functions that I have come across seem to hash everything together. If this is the case, how does one get the password back out for comparison? My biggest question is, how is salting a users' password safer than just hashing the password? If a database was ever to be compromised, the hash along with the salt is in the database. Isn't this all that a hacker would need?

I also found another post here on SO where another developer said :

"Ensure your salt and algorithm are stored separately from the database"

I would like to store the salt in the database. Is this really a problem if I do?

I'm looking for some help on understanding how this works and also what the best practice might be. Any help is greatly appreciated.


EDIT: I want to thank everyone for their responses and ideas. Even though I may be more confused now, it has certainly been a learning experience for me. Thanks again guys.

解决方案

An hash function always return the same value for the same input string. Let's say my user (Alice) has the password secret. Hashing secret using md5() leads to the following hash

5ebe2294ecd0e0f08eab7690d2a6ee69

Using a dictionary (a list of common words and password) or one of the various sites that offer you that service, the attacker (Mallory) can easily find out the password is secret when he sees in his dictionary that 5ebe2294ecd0e0f08eab7690d2a6ee69 = secret.

The process of salting before hashing makes it harder to use a dictionary attack without knowing your salt. Consider the following:

<?php
$salt = '@!#%$@#$@SADLkwod,sdaDwqksjaoidjwq@#@!';
$hash = md5($salt . 'secret');

The resulting hash is now b58ad809eece17322de5024d79299f8a but Alice's password is still secret. Now if Mallory gets her hands on the salted hash, chances are she will not find the answer in her dictionary. If she does, the dictionary will give her the wrong answer.

Never store a static salt in your database. Preferably store it with your application's configuration (which by the way should not be available from the web).

If you are going to use a dynamic salt, you are going to need to use the database. Use a non-null column of existing valid data to build your salt on (blowfish-encrypted string of username based on a secret encryption key is usually cryptographically secure). Do not use a separate column for the salt. If you cannot use an existing column, incorporate your salt in the same column than your hash. For example, use the first 32 characters for your 128-bits salt and then the last 40 for your 160-bits hash. The following function will generate such an hash:

function seeded_sha1($string, $seed_bits) {
    if(($seed_bits % 8) != 0) {
        throw new Exception('bits must be divisible by 8');
    }

    $salt = '';
    for($i = 0; $i < $seed_bits; $i+=8) {
        $salt .= pack('c', mt_rand());
    }

    $hexsalt = unpack('h*hex', $salt);

    return $hexsalt['hex'] . sha1($salt . $string);
}

function compare_seeded_sha1($plain, $hash) {
    $sha1 = substr($hash, -40);
    $salt = pack('h*', substr($hash, 0, -40));

    $plain_hash = sha1($salt . $plain);
    return ($plain_hash == $sha1);
}

If an attacker gets in your database using SQL injection, at least the hashes he/she retrieves won't be useful since he/she won't have access to your application configuration. If your server gets rooted, it's pretty much game-over no matter what you do.

Note: There are other types of attack possible on md5() which is why you use more secure hashing algorithm, sha1() for example. Or, even better, use the Portable PHP password hashing framework, which has been designed with security in mind and is backwards compatible with pretty much any PHP version.

require('PasswordHash.php');

$pwdHasher = new PasswordHash(8, FALSE);

// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );

// $hash would be the $hashed stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
    echo 'password correct';
} else {
    echo 'wrong credentials';
}

这篇关于如何在我的登录密码中实现salt?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆