在阅读了一整天的密码散列/加盐处理后(没有谎言!),我需要找到一个有效的解决方案,可以持续使用,并且足够安全适用于使用共享代码库的各种不同站点/应用程序。
所以,这是一个 MySQL 用户表的想法:
users { id, username, password_hash, password_salt }
..和伪代码:
$s_algo = 'sha1';
$i_iterations = 1000;
$s_password = 'mypw123xyuACE&.!3';
$s_salt = hash($s_algo,uniqid(mt_rand(),true));
$s_result = $s_password;
for ($i = 0; $i < $i_iterations; $i++) {
$s_result = hash($s_algo,$s_result . $s_salt);
}
echo 'Password: ' . $s_password . "\n";
echo 'Algorithm: ' . $s_algo . "\n";
echo 'Iterations Completed: ' . $i . "\n";
echo 'Salt : ' . $s_salt . "\n";
echo 'Result: ' . $s_result . "\n";
echo 'Length: (Salt:) ' . strlen($s_salt) . ' (Result:) ' . strlen($s_result) . "\n";
PHP 和 MySQL 之间的交互 (SQL) 被视为读取,PHP 代码的位也是如此,这些代码在身份验证时根据存储的(加盐的)哈希实际验证来自用户空间的给定密码。这不是火箭科学。这是从已经做了所有这些事情的角度来看的,但是使用未加盐的纯哈希密码存储。
根据我的阅读,我怀疑关于 $s_algo 到底应该是什么(好吧,可能不是 md5)以及 $i_iterations 可能会有无休止的争论。因此,让我们只考虑它们是此问题场景中的变量,它们可能会根据特定上下文(即存储限制、服务器负载问题等)发生变化。
撇开这些不谈,这种在 PHP 中创建每个用户加盐密码的方法是否普遍合理? “for”循环是否需要在那里?最初的盐创建代码可以吗?在存储方面,salt-length 是否过度杀伤(等于最终的散列长度)。请人们,挑漏洞(但不要太多!)..
其他想法:
- hash_hmac() 怎么样 - 这是对多个 hash() 迭代的重大改进吗?
-PBKDF2?
最佳答案
抱歉,我会在帖子上发表评论,但还没有获得足够的代表。
我会为我的哈希算法使用 SHA256,并将迭代次数保持在 25 左右。超过这个数,它真的有点过分了。我对一个框架使用了一个非常相似的解决方案,我现在已经应用于六个站点。我选择创建一个过于复杂的随机字符生成器,但我在很多其他地方使用过它,包括标记化财务数据。
另一个编辑:使用这样的随机字符生成器作为盐:
function randomChar($length) {
$characters = array("A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "~", "!", "@", "#", "%", "^", "&", "(", ")", ":", "{", "[", "]", "}", "|", "<", ">", ".", ",", "/", "?", "_", "+", "-", "=");
$charactersNumber = count($characters);
$charactersNumber--;
$randomLength = 0;
while ($randomLength < $length) {
$currentCharacter = $characters[rand(0,$charactersNumber)];
if ($currentCharacter == $previousCharacter) {
$currentCharacter = $characters[rand(0,$charactersNumber)];
}
$random .= $currentCharacter;
$previousCharacter = $currentCharacter;
$randomLength++;
}
return $random;
}
对迭代问题的回应: 如果 x = hash(password + salt) 从那时起 x = hash(x + salt)
x 的 1 次评估需要 10 毫秒,然后 2 次需要 20 毫秒,依此类推。 所以... 25 次评估 = 250 毫秒 1000 = 10,000 毫秒。
虽然每个都不需要 10 毫秒,但即使超过 1000 0.5 毫秒也仍然是半秒。
如果您只接受字母数字密码,并且密码长度为 8 个字符,则每次迭代都会增加 62^8(如果他们还没有找到密码)更多的哈希值,因为他们必须为每个组合执行另一个 has他们尝试过。
关于php - 希望找到一个可用的 PHP/MySQL 应用程序密码加盐解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4557892/
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir
我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下