在我的上一个问题"用于存储机密的可移植数据库"中,最好的答案直到现在告诉使用sqlite-crypt.
阅读sqlite-crypt文档,打开数据库的新参数是pass-phrase.当然,我不想硬编码密码,所以我在想什么是存储密码的最佳,简单和快速的方法?
我正在尝试为我的密码正确地执行每个用户和站点范围的盐.这是我得到的:
require('../../salt.php'); //this is above the web root and provides $salt variable
$pw = mysql_real_escape_string($_POST['pw']);
$per_user_salt = uniqid(mt_rand());
$site_salt = $salt //from salt.php that was required on first line
$combine = $pw . $per_user_salt . $site_salt;
$pw_to_put_in_db = hash("sha512", $combine);
Run Code Online (Sandbox Code Playgroud)
这是正确的吗?谢谢
要散列密码(单向),看起来像bcrypt是最好的.
我即将开始使用jBCrypt,但我有一些担忧:
是否有一个类似的,更主流的图书馆,每个人都在使用,我错过了某种方式?(Java,开源)
还是它实际上是"最主流的"?
假设我有一个密码:
AAABBBCCCDDD我可以很容易地给人A第一部分(AAA),人B第二部分等等.
但有四个人中的任何一个可以从我给他们的部分文本中解密/形成密码吗?显然,仅从AAA和DDD部分无法形成密码.
怎么样?:)
几年后,我在stackoverflow上询问了如何使PHP密码存储安全.在主要答复建议使用以下哈希算法:
function hash_password($password, $nonce) {
global $site_key;
return hash_hmac('sha512', $password . $nonce, $site_key);
}
Run Code Online (Sandbox Code Playgroud)
答案建议使用随机的随机数.有一个随机的随机数比简单的独特的随机数有什么优势吗?
例如,每个用户可以拥有自己的ID,但不会改变.但是,我们假设用户ID是顺序的(使用MySQL的自动增量功能构建),因此不是随机的.用户ID是一个好的nonce还是随机性很重要?
现在,每个用户都可以选择用户名.每个用户都有自己的用户名,该用户名不会更改,两个不同的用户不能拥有相同的用户名.用户名仍然不是随机的,但它们也不是顺序的.用户名是否足够好作为nonce?它会比使用用户ID更好吗?
我的问题来自于 如何使用河豚散列长密码(> 72个字符)
我使用bcrypt(河豚)来哈希密码.所以,正如我从这个问题中发现的那样 https://security.stackexchange.com/questions/39849/does-bcrypt-have-a-maximum-password-length
它的字符数限制为72.
所以,我开始考虑限制密码的最大长度,但是在这些问题及其答案之后
所有人都说是反对的.提到的东西,比如
a maximum length specified on a password field should be read as a SECURITY WARNING通过这个答案 - /sf/answers/6980711/所以,我认为我不符合其中一个案例.当然,我同意愚蠢的限制,例如最大长度10,甚至更糟,8或6,但不是30,40或更长的密码(盐渍)被认为是安全的?从这篇文章(虽然有点旧),但它说
it can make only 71,000 guesses against Bcrypt per second
Run Code Online (Sandbox Code Playgroud)
这适用于8个字符的密码.因此,我想象自定义彩虹表会蛮力一个30个或更多字符密码(考虑到每个密码都有自己的盐),因为彩虹表大小呈指数增长
引用同一篇文章的评论
每次在密码中添加一个字符时,都会以指数方式增加通过暴力破解所需的难度.例如,8-char密码的密钥空间为95 ^ 8组合,而20-char密码的密钥空间为95 ^ 20组合.
因此,对于一个20长度密码与bcrypt根据那将是必要95 ^ 20 /(71 000*3600*24*365)~10年28度(如果我做对了)
qsn1:现在,在这种情况下,使用blowfish有一个意思是不要将密码最大长度限制为72,因为在任何情况下都会被截断,因此这里没有额外的安全性增益.
qsn2:即使存在salt(每个用户都是唯一的并保存在db中),毕竟我想在密码中添加pepper(在应用程序中硬编码而不是保存在db中).我知道是否会增加一些额外的安全性,但我认为以防万一db(或db backup)只是泄露,胡椒将是有用的.
https://security.stackexchange.com/a/3289/38200
所以,为了能够添加20个字符胡椒,我需要将密码最大长度设置为50左右.我想这样:让我们说用户是使用70个字符,在大多数情况下(如果不是全部),它将是一些短语或类似的,而不是生成强大的字符,因此将用户限制为50最大长度并添加另一个20-22更安全字符胡椒肯定更安全/随机.另外,让我们说黑客正在使用"常用短语"的彩虹表,我认为有更高的机会,这72 character common phrase将被黑客攻击,而不是50 character common phrase + 22 character …
encryption passwords password-policy password-storage password-encryption
假设知识
Hashing、Salting、PBKDF[1-2]
问题
我使用像 PBKDF2 这样的缩放散列/加盐算法在我的数据库中存储密码。我想‘嘿,如果我将密码散列 20000 次,那应该足够安全,可以抵御暴力攻击,对吗?它是真的。直到明年更好的电脑问世。
可能的解决方案
撇开加密密钥长度和盐长度的问题(也可以合并到这个解决方案中)我想,如果每 N 天,我重新散列数据库中的所有密码会怎样。所以它们被散列了 20,000 次,然后一周后,我又对它们进行了 500 次散列,使它们总共 20,500 次。将它在数据库中散列的次数存储在某处。这个想法是随着技术的进步增加哈希计数。
现有的类似实现
BCrypt引入了一个工作因素来增加哈希密码所需的时间:
PBKDF2使用多次迭代来做同样的事情。这被 Mac OS-X、windows 和 linux 用于文件级加密。Wi-Fi网络也使用它的实现。
任何人都可以看到这个问题吗?这个已经试过了?是否有一种算法可以接受预先散列的密码并将其重新散列“N”次?
编辑
问题不是多重散列是否安全(这已经过尝试和测试)。问题是重新散列以提高安全性,而不必让用户重新设置他们的密码
解决方案:礼貌与 JVestry 讨论
因此,每隔“N”天重新散列所有密码是浪费时间,因为黑客可以使用数据库的旧副本破解它。但是,如果您将随时间增加哈希计数的概念与密码更新策略相结合,这个概念是合理的。
实施
所有密码每 30 天过期一次。当它们更新时,它们的哈希计数器会增加。因此,昨天的密码重置将比 20 天前的密码更难破解。哈希计数器可以存储或从使用最后修改日期的算法得出。
谢谢!
TTD
我在很多文章中都读过,我们应该在散列之前将一个独特的盐与每个密码结合起来并将盐存储在数据库中进行验证,但如何将密码本身用作盐?
这样做会有好处,因为盐对于每个盐都是唯一的,并且它将被隐藏,因为它将被存储在任何地方.
我上面给出的一个简单例子是:
$hashToStore=sha1(strrev($password).$password);
Run Code Online (Sandbox Code Playgroud)
上面我只是颠倒密码并将其用作盐(我将做更复杂的事情,然后在开发中将其反转.)
这是存储密码的更好方法,还是一种不好的做法.
PS:我完全了解php最新的内置功能, crypt()并在现实世界中使用它,但还想要上面的评论.
我有一个表单,其中包含名称属性username的文本框和另一个名称为attribute password的表单.我还有一个名为user和pass的数据库.当我的用户注册时,它将用户列的用户名和密码添加到传递列.
我如何制作一个MySQL查询来检查表单是否提交了正确的用户名和密码,然后如果它确实有一个分支让我输入代码,如果它成功了?
我真的需要一些代码,这一点并不顺利我知道它应该是类似的东西SELECT * FROM table WHERE username == $username AND...然后我被卡住了因为我在数据库中有一个MD5密码,并且第一位可能是错误的.请帮忙.:)
谢谢
我有一个白帽子黑客的朋友.他说md5并不是那么糟糕,实际上它确实非常安全,只要我们正确使用它.
我相信他是对的.据我所知,有三种方法可以打破哈希:
我和我的朋友认为Blowfish并不是真的有需要,也可能是有害的,因为它可以减慢密码验证过程,并且它可以与DDOS攻击一起使用,即使使用较少的资源,也可以分解服务器.
所以,我想确保遵循算法真的安全吗?并且,是否有真正的理由选择Blowfish哈希算法?
// return a 256 bit salt + 128 bit md5 binary hash value
function hash(password, salt=null)
{
salt = (salt != null) ? salt : Random256BitBinaryValueGenerator();
// What about using another user-specified parameter, like email address as salt?
return salt + md5(salt + password) + md5(password + salt);
// Or just use a non-cryptographic hash algorithm like crc32 to prevent collisions:
// return salt + md5(salt + password) + …Run Code Online (Sandbox Code Playgroud)