更新:请注意我不是在询问盐是什么,彩虹表是什么,字典攻击是什么,或盐的目的是什么.我在查询:如果你知道用户的salt和hash,那么计算密码是不是很容易?
我理解这个过程,并在我的一些项目中自己实现它.
s =  random salt
storedPassword = sha1(password + s)
在您存储的数据库中:
username | hashed_password | salt
我所看到的盐析的每次实施都会在密码的末尾添加盐,或者开始:
hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)
因此,来自黑客的字典攻击是值得他的盐(哈哈),只需针对上面列出的常见组合中存储的盐运行每个关键字.
当然,上述实现只是为黑客增加了另一个步骤,而没有真正解决潜在的问题?有什么替代方法可以解决这个问题,还是我误解了这个问题?
我唯一能想到的就是有一个秘密混合算法,它以随机模式将salt和密码绑定在一起,或者将其他用户字段添加到散列过程中,这意味着黑客必须能够访问数据库和代码才能获得花边他们为字典攻击证明富有成效.(更新,正如评论中指出的那样,最好假设黑客可以访问您的所有信息,因此这可能不是最好的).
让我举一个例子,说明我如何建议黑客用密码和哈希列表来破解用户数据库:
来自我们黑客数据库的数据:
RawPassword (not stored)  |  Hashed   |     Salt
--------------------------------------------------------
letmein                       WEFLS...       WEFOJFOFO...
通用密码字典:
   Common Password
   --------------
   letmein
   12345
   ...
对于每个用户记录,循环公共密码并对其进行哈希:
for each user in hacked_DB
    salt = users_salt
    hashed_pw = users_hashed_password
    for each common_password
        testhash = sha1(common_password + salt)
        if testhash = hashed_pw then
           //Match!  Users password …据我了解,生成盐的最佳做法是使用源代码中存储的一些神秘公式(甚至魔术常量).
我正在研究一个我们打算作为开源发布的项目,但问题是源代码是生成盐的秘密公式,因此能够在我们的网站上运行彩虹表攻击.
我认为很多人在我面前都考虑过这个问题,我想知道最佳做法是什么.在我看来,如果代码是开源的话,根本就没有盐,因为盐可以很容易地进行逆向工程.
思考?
我正在看一些我自己没有写过的代码.代码尝试使用SHA512散列密码并仅使用time()盐作为密码.是time()太简单盐这或者是这个代码安全吗?
感谢您的回答和评论.我将在此为新读者总结一下:
random, evenly distributed, high entropy盐?好吧,那么我用随机字符串32 char long替换time()怎么样.可以通过在一组字母表字符上循环32次来生成随机字符串.听起来不错吗?
我目前使用
base64_encode()来编码用户的密码,这很好用,因为它允许我简单地使用base64decode()来解密一个单词的密码,如果他们丢失密码就发送给那里的电子邮件.  
我一直在阅读密码,很多人似乎都说你应该使用sha1()来编码密码.我全都是为了提高系统的安全性但是如果我转换为使用shal()那么我将无法向用户发送丢失的密码.
你用什么?你能给我一些建议吗?有没有办法解密可读密码来通过电子邮件发送给用户?
当我输入这个问题时,我只是记得有些论坛在请求时没有给你发密码,而是发送一个特殊的链接来重新设置你的密码,我猜这是因为他们无法解密你的密码?
//what I use now
$password_encoded = base64_encode($password);
//what I am considering using
$password_encoded = sha1($password);
Android和Java提供了一个加密API,相对来说非常容易用于加密非专家.
但是既然我们知道没有任何代码可以真正受到保护免受逆向工程,特别是用作种子或共享机密的字符串常量,我想知道:在Android应用程序中经历加密和解密的磨难有什么意义?
我错过了什么吗?
试图让我的问题更清晰,更具体:假设我已经在使用特定字符串的应用程序通过代码,在代码(即没有用户数据)必须是秘密的:一种方法是将它们存储在加密的形式在编译.apk并在运行时解密它们(使用模糊的硬编码密码).另一种方法是将它们以加密形式存储在远程服务器中,在运行时获取它们(通过Internet)并解密(使用共享密码)它们.
我认为两者之间没有太大的区别,因为两者都要求(反向工程)代码中存在"密钥".
有这个问题的解决方案吗?
如果没有解决方案,为什么要加密?
我正在阅读有关如何安全地存储密码的相互矛盾的建议.我所知道的不是使用MD5!我见过人们主张使用PHP的bcrypt功能,这看起来好像它会占用服务器的处理器.我见过盐的倡导者,并主张不使用盐.
这一切都是如此不清楚.关于如何安全地存储密码,是否有真实可信的建议?
编辑:经过大量研究后,我发现了一篇文章;登录:深入讨论该主题:http://www.usenix.org/publications/login/2004-06/pdfs/alexander.pdf
我知道如何设置使用表单身份验证并使用消化密码(例如,SHA-256)的vanilla容器管理安全性.像这样的东西:
<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>jdbc</realm-name>
    <form-login-config>
        <form-login-page>/login.jsf</form-login-page>
        <form-error-page>/login-error.jsf</form-error-page>
    </form-login-config>
</login-config>
<form action="j_security_check">
    <p><label>
        Username:<br/>
        <input type="text" name="j_username" />
    </label></p>
    <p><label>
        Password:<br/>
        <input type="password" name="j_password" />
    </label></p>
    <p>
        <button type="submit">Submit</button>
    </p>
</form>
非常简单 - 但我真正希望能够做的是用全局盐和用户名加密密码.是的,我知道这并不理想,但现在,我只是在构建一个概念验证.
容器(GlassFish 3,在这种情况下)可以为我做这个,还是我必须编写自己的登录过滤器?我之前已经完成了(对于J2EE应用程序)但我的直觉告诉我,现在我必须采用更严格的方法来使用Java EE 6.
我正在写一个android密码管理器应用程序,我想在某处存储主密码,但我不知道在哪里.我应该使用我选择的硬编码密码加密用户提供给我的主密码,然后将其存储到数据库中吗?或者我应该做别的事吗?
salt ×5
passwords ×4
security ×4
hash ×3
php ×3
android ×2
encryption ×2
java ×2
asp.net ×1
cryptography ×1
database ×1
decompiling ×1
jaspic ×1
java-ee ×1
jsf ×1
jsf-2 ×1
md5 ×1
open-source ×1
rainbowtable ×1