我应该为密码存储哈希吗? [英] Am I supposed to store hashes for passwords?

查看:127
本文介绍了我应该为密码存储哈希吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用户系统和密码:我正在看MD5的东西,我想知道什么是密码的正常/良好做法。现在,我认为人们超级加密密码并存储哈希值。如果是这样,密码检查如何工作?我只是输入密码再次通过加密过程,然后用存储的密码检查哈希,是否正确?



这个问题可能与上述矛盾,但是我的盐永远是一个随机产生的价值?如果是这样,什么时候可以使用?



编辑:除了密码,在用户系统中,还应该加密为好实践?他们加密用户名还是其他任何东西?



第二个编辑:什么是单向哈希?我的意思是说,技术上我不能逆向工程我的源代码?也许这是一个坏的问题,因为我不太了解单向散列。

解决方案

首先你创建一个盐。 / p>

注意示例以PHP编写

  //设置一个盐,这不是随机的,但实际上并不一定是
$ salt = sha1(microtime());

然后加密密码

  //首先我们哈希的密码,然后用salt哈希结果XOR它
$ hash = sha1(sha1($ password)^ $ salt);

存储 $ hash $ salt 在数据库中。



当用户输入密码与哈希比较时

  if(sha1($ enter_password)^ $ salt)== $ hash)
//正确密码

永不以可逆格式存储密码。另外,我建议不要使用MD5作为哈希。


编辑:除了密码,在用户
系统中,还有什么应该加密
作为一个很好的做法?他们加密
用户名还是其他任何东西?


密码未加密,它们是散列的。将哈希(非常简单化)作为一个数字,并将其乘以十。说我想哈希数字 30 。我会说 30 * 10 ,并将 300 作为我的哈希为 30 。请注意,您无法从 300 中导出 30 ,而不知道哈希函数的工作原理。



这是一个非常简单的哈希,如果你知道它总是乘以十,那么你可以很容易地扭转它。 现在看看SHA1哈希函数。很多更复杂。它不能简单地逆转。



你会发现很少是密码散列的东西,没有什么是加密的。加密数据库所需的开销大小将是巨大的。



我假设可以将类似的盐/散列图案应用于用户名,但是您有陷阱。如果您想在代码中的某个地方使用该用户名,该怎么办?如果你想检查,以确保它是唯一的表?


第二编辑:什么是单向哈希?我的
的意思是说,技术上我可以不用
工程师来我的源代码?也许这是
a不好的问题,因为我不知道
关于单向散列。


或点击此处)。单向哈希就是这样。单向映射 A => B ,没有别的。 B!=>一个 A 不能是除 B 之外的任何东西。



有人提到了一个 XOR 操作的表现。虽然我觉得表现很可忽略,但我经历了一个快速测试。

  function microtime_float()
{
list($ usec,$ sec)= explode(,microtime());
return((float)$ usec +(float)$ sec);
}

现在运行

  $ start_time = $ this-> microtime_float(); 

($ i = 0; $ i <100000; $ i ++)
{
$ sha = sha1(sha1(microtime())。sha1(microtime ));
}

$ end_time = $ this-> microtime_float();

echo1000 in。 ($ end_time- $ start_time)。 对于CAT\\\
;


$ start_time = $ this-> microtime_float();

($ i = 0; $ i <100000; $ i ++)
{
$ sha = sha1(sha1(microtime())^ sha1(microtime ));
}

$ end_time = $ this-> microtime_float();

echo1000 in。 ($ end_time- $ start_time)。 for XOR\\\
;

重复一遍你想要的。 初始撰写使用错误日志,我得到以下结果:

  1000 in 0.468002796173 XOR 
1000 in 0.465842008591 XOR
1000 in 0.466115951538 XOR
1000 in 0.498080968857 CAT
1000 in 0.506876945496 CAT
1000 in 0.500174045563 CAT


User System and Passwords: I was looking through MD5 stuff, and I am wondering what is the normal/good practice for passwords. Right now, I think people super encrypt the passwords and store the hashes. If so, how does password checking work? I just have the input password go through the encryption process again and then check the hash with the stored one, correct?

This question may contradict the above, but should my salt ever be a randomly generated value? If so, when may it be useful?

Edit: Other than passwords, in a user system, what else should be encrypted as a good practice? Do they encrypt usernames or anything else?

2nd Edit: What is a one-way hash? I mean, technically, can I not reverse engineer my source code? Maybe this is a bad question because I do not know much about one-way hashing.

解决方案

First you create a salt.

Note examples are written in PHP

// Setup a salt, this isn't "random" but it doesn't really have to be
$salt = sha1(microtime());

Then salt the password

// First we hash the password, then XOR it with the salt hashing the result
$hash = sha1(sha1($password) ^ $salt);

Store the $hash and $salt in the database.

When the user enters a password compare it to the hash

if(sha1(sha1($entered_password) ^ $salt) == $hash)
    // Correct password

Never store passwords in a reversible format. Also I would advise against using MD5 as a hash.

Edit: Other than passwords, in a user system, what else should be encrypted as a good practice? Do they encrypt usernames or anything else?

Passwords aren't encrypted, they are hashed. Picture a hash (very simplistic) as something that takes a number and multiplies it by ten. Say I want to hash the number 30. I would say 30*10 and get 300 as my "hash" for 30. Note that you cannot derive 30 from 300 without knowing how the hash function works.

That's a very simplistic "hash" and if you know it always multiplies by ten then you could easily reverse it. Now take a look at the SHA1 hash function. It's much more complicated. It can't simply be reversed.

You will find that rarely is anything except the password hashed, and nothing is encrypted. The amount of overhead you would have with encrypting your database would be enormous.

I suppose you could apply a similar salt / hash pattern to the username, but then you have pitfalls. What if you want to use that username somewhere in your code? What if you want to check to make sure it's unique to the table?

2nd Edit: What is a one-way hash? I mean, technically, can I not reverse engineer my source code? Maybe this is a bad question because I do not know much about one-way hashing.

See above (or click here). A one way hash is just that. One way mapping. A => B and nothing else. B !=> A, and A can't be anything except B.

Someone mentioned the performance of an XOR operation. While I feel performance is largely negligible I ran a quick test.

function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

Now run

$start_time = $this->microtime_float();

for($i = 0; $i < 100000; $i++)
{
 $sha = sha1(sha1(microtime()) . sha1(microtime()));
}

$end_time = $this->microtime_float();

echo "1000 in " . ($end_time-$start_time) . " for CAT\n";


$start_time = $this->microtime_float();

for($i = 0; $i < 100000; $i++)
{
 $sha = sha1(sha1(microtime()) ^ sha1(microtime()));
}

$end_time = $this->microtime_float();

echo "1000 in " . ($end_time-$start_time) . " for XOR\n";

Repeat as much as you want. The initial writeup uses the error log and I got the following results:

1000 in 0.468002796173 XOR
1000 in 0.465842008591 XOR
1000 in 0.466115951538 XOR
1000 in 0.498080968857 CAT
1000 in 0.506876945496 CAT
1000 in 0.500174045563 CAT

这篇关于我应该为密码存储哈希吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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