- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在很多文章中读到,我们应该在散列之前为每个密码组合一个唯一的盐,并将盐存储在数据库中以供验证,但是如何使用密码本身作为盐呢?
这样做会有好处,因为每个盐都是独一无二的,而且它会被隐藏起来,因为它不会存储在任何地方。
上面我可以给出的一个简单例子是:
$hashToStore=sha1(strrev($password).$password);
上面我只是反转密码并将其用作盐(我将做一些更复杂的事情然后只是在开发中反转它。)
这是一种更好的密码存储方式,还是一种不好的做法。
PS:我完全了解 php 最新的内置函数,例如 crypt()
并在现实世界中使用它,但仍希望对上述内容进行审查。
最佳答案
A common mistake is to use the same salt in each hash. Either the salt is hard-coded into the program, or is generated randomly once. This is ineffective because if two users have the same password, they'll still have the same hash. An attacker can still use a reverse lookup table attack to run a dictionary attack on every hash at the same time. They just have to apply the salt to each password guess before they hash it. If the salt is hard-coded into a popular product, lookup tables and rainbow tables can be built for that salt, to make it easier to crack hashes generated by the product.
A new random salt must be generated each time a user creates an account or changes their password.
[…] It's easy to get carried away and try to combine different hash functions, hoping that the result will be more secure. In practice, though, there is very little benefit to doing it. All it does is create interoperability problems, and can sometimes even make the hashes less secure. Never try to invent your own crypto, always use a standard that has been designed by experts. Some will argue that using multiple hash functions makes the process of computing the hash slower, so cracking is slower, but there's a better way to make the cracking process slower as we'll see later.
Here are some examples of poor wacky hash functions I've seen suggested in forums on the internet.
md5(sha1(password))
md5(md5(salt) + md5(password))
sha1(sha1(password))
sha1(str_rot13(password + salt))
md5(sha1(md5(md5(password) + sha1(password)) + md5(password)))Do not use any of these.
Salt should be generated using a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG). CSPRNGs are very different than ordinary pseudo-random number generators, like the "C" language's rand() function. As the name suggests, CSPRNGs are designed to be cryptographically secure, meaning they provide a high level of randomness and are completely unpredictable. We don't want our salts to be predictable, so we must use a CSPRNG. The following table lists some CSPRNGs that exist for some popular programming platforms. (PHP: mcrypt_create_iv, openssl_random_pseudo_bytes)
The salt needs to be unique per-user per-password. Every time a user creates an account or changes their password, the password should be hashed using a new random salt. Never reuse a salt. The salt also needs to be long, so that there are many possible salts. As a rule of thumb, make your salt is at least as long as the hash function's output. The salt should be stored in the user account table alongside the hash.
To Store a Password
- Generate a long random salt using a CSPRNG.
- Prepend the salt to the password and hash it with a standard cryptographic hash function such as SHA256.
- Save both the salt and the hash in the user's database record.
To Validate a Password
- Retrieve the user's salt and hash from the database.
- Prepend the salt to the given password and hash it using the same hash function.
- Compare the hash of the given password with the hash from the database. If they match, the password is correct. Otherwise, the password is incorrect.
At the bottom of this page, there are implementations of salted password hashing in PHP, C#, Java, and Ruby.
In a Web Application, always hash on the server
If you are writing a web application, you might wonder where to hash. Should the password be hashed in the user's browser with JavaScript, or should it be sent to the server "in the clear" and hashed there?
Even if you are hashing the user's passwords in JavaScript, you still have to hash the hashes on the server. Consider a website that hashes users' passwords in the user's browser without hashing the hashes on the server. To authenticate a user, this website will accept a hash from the browser and check if that hash exactly matches the one in the database. This seems more secure than just hashing on the server, since the users' passwords are never sent to the server, but it's not.
The problem is that the client-side hash logically becomes the user's password. All the user needs to do to authenticate is tell the server the hash of their password. If a bad guy got a user's hash they could use it to authenticate to the server, without knowing the user's password! So, if the bad guy somehow steals the database of hashes from this hypothetical website, they'll have immediate access to everyone's accounts without having to guess any passwords.
This isn't to say that you shouldn't hash in the browser, but if you do, you absolutely have to hash on the server too. Hashing in the browser is certainly a good idea, but consider the following points for your implementation:
Client-side password hashing is not a substitute for HTTPS (SSL/TLS). If the connection between the browser and the server is insecure, a man-in-the-middle can modify the JavaScript code as it is downloaded to remove the hashing functionality and get the user's password.
Some web browsers don't support JavaScript, and some users disable JavaScript in their browser. So for maximum compatibility, your app should detect whether or not the browser supports JavaScript and emulate the client-side hash on the server if it doesn't.
You need to salt the client-side hashes too. The obvious solution is to make the client-side script ask the server for the user's salt. Don't do that, because it lets the bad guys check if a username is valid without knowing the password. Since you're hashing and salting (with a good salt) on the server too, it's OK to use the username (or email) concatenated with a site-specific string (e.g. domain name) as the client-side salt.
来源:https://crackstation.net/hashing-security.htm
所以,回答你的问题,坏主意,非常糟糕的主意。
关于php - 使用密码本身作为盐是个好主意吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24415950/
我正在使用一个以明文形式存储密码的旧应用程序。我已将应用程序移植到 spring 3 mvc + security。我还成功地让 spring security 使用 sha256 + 基于用户名的盐
我试图按照 here. 中的代码获取哈希密码从中,我目前只使用 salt 的代码。方法,hash方法和isExpectedPassword方法。 我从文本字段获取密码: char[] passChar
我已经阅读了有关此问题的许多问题,但许多答案相互矛盾或我不明白。 您应该始终将密码存储为哈希值,而不是纯文本。但是您是否应该将盐(对于每个用户来说都是唯一的)存储在数据库中的散列密码+盐旁边。这对我来
我有一些 php 脚本,使我的用户能够使用电子邮件创建帐户。然后,他设置了一个经过哈希处理的密码,生成了一个盐并将其存储在我的数据库中。现在我正在重置密码,工作正常,但新密码(更改密码,即使其正确的密
我在申请中使用 shiro 进行身份验证。我使用加盐的散列密码,并将它们存储在我的数据库中,如下所示: private User createUserWithHashedPassword(St
我正在尝试找出在桌面应用程序中应该将应用程序 secret 和 key 存储在何处或如何存储。 例如 facebook 应用程序 key 或 dropbox key 和 secret 。 所以我读到我
ASP.NET 成员资格如何生成他们的 salt key ,然后他们如何对其进行编码(即是 salt + 密码还是密码 + salt)? 我正在使用 SHA-1使用我的成员(member)资格,但我想
我正在设置一个cookie。像这样的东西: $_COOKIE['test'] = SHA1('124'.'mysalt'); 现在 124 是我想要的 ID。所以在我的 MySQL 表中,我尝试运行如
我的应用需要加密一些数据(用户 session token )。我看到的大多数示例都有一种使用密码和盐生成 key 的方法,例如: public static Key generateKey(char
我想在数据库中的密码旁边存储一个(随机)盐。现在,问题是: 我应该将其存储为哈希值还是纯文本?有什么区别吗(更安全,更快?)?我应该付出多少努力来创建随机字符串? 示例代码: //Creati
当我收到此错误时,我正要在 Windows Azure 上部署我的服务: Error: The provided configuration file contains XML that could
如何在 C# 中创建以下 PHP 代码? PHP代码: 我将不胜感激任何形式的帮助。一直在测试以下内容: https://stackoverflow.com/a/1300927/7312781 但它
谁能推荐一个使用 javascript 创建 sha1 salt 的好方法? 最佳答案 首先,阅读盐的用途以确保您理解它。 This和 this会让您入门,但您应该阅读更多内容。 基本上,任何适当大小
我知道这可能是一个常见问题,网上有很多关于为密码哈希生成安全盐的文章。到目前为止,我已经了解到mcrypt_create_iv通常用于加密的初始化向量,它可用于安全地创建盐,特别是在针对MCRYPT_
我知道这个话题已经被讨论了一百万次。但这对我来说是新的,我读得越多,就越不了解实际发生或应该发生的事情。 我在用户密码的散列存储中添加了每个用户盐,因此存储的密码散列如下所示:hash(passwor
我正在学习本教程 ( http://kowsercse.com/2011/09/04/kohana-tutorial-beginners/ ) 并遇到此错误消息: Kohana_Exception [
我是一名优秀的程序员,十分优秀!