草庐IT

php - 这是一个适当的登录和注册加密系统

coder 2024-04-14 原文

显然,散列用户名和密码并将其保存为cookie并使用经过消毒的cookie数据登录对你们(或我的站点的安全性)来说是不够的。
这种方法够好吗?
注册程序:

$salt= date('U');
$username= hash('sha256', $salt. $_POST['username']);
$password= hash('sha256', $salt. $_POST['password']);
$token = hash('sha256', $salt. (rand(1,10000000000000000000000000000000000000000000)));

要手动登录,用户输入用户名和密码,然后通过散列传递并匹配。
成功登录后,将为用户创建两个库克。一个持有未加密的用户名,另一个持有哈希标记。
当用户访问时,如果设置了cookies,站点将散列用户名,然后使用这两个值登录。
这种方法的优点是避免了将用户的密码存储在计算机上的任何位置。有人可以破解令牌并访问他们的帐户,但至少我不会危害用户的密码…
回答MySQL real_escape string and cookies的人说,在cookies中存储用户数据是错误的。这会转移问题吗?

最佳答案

为什么你需要存储密码,甚至是加密版本?您的站点是否正在访问后端的第三方api,该api执行http basic身份验证或其他操作?
很不幸,你的问题没有明确的答案。”“适当”对不同的人意味着不同的东西。对于安全性问题,我不确定是否有可能做到“足够合适”或“足够安全”,也就是说,我是如何处理登录和密码安全的。在数据库的users表中,我有3个与登录相关的列:
用户名

密码散列
username列是纯文本。salt列是随机选择的字母数字字符的64字符字符串。passwordHash列是用户的密码,它与salt值连接在一起,然后进行不可逆的散列。我用SHA256做散列。盐是64个字符,因为这是SHA256产生的。为了在散列字符串中产生足够的可变性,最好至少具有与散列一样长的salt值。
当用户提交登录表单时,我对用户名进行数据库查询。如果找不到用户名,我将向用户显示“无效用户名和/或密码”错误。如果找到用户名,我将salt与密码连接起来,散列它,看看它是否等于passwordHash值。如果没有,则向用户显示完全相同的错误。
无论用户名是错误的,还是密码是错误的,或者两者都是错误的,都可以显示完全相同的错误消息。你给黑客的线索越少越好。此外,每当用户更改密码时,我也会给他们一个新的salt。在那个时间点做这件事真的很容易,而且它能让盐值更新鲜一些。
这种每个用户有不同的盐的系统称为动态盐析。如果黑客试图使用rainbow tables对用户的密码进行反向工程,这将使黑客的工作变得非常复杂。更不用说以不可逆转的散列形式存储密码对于阻止任何人确定用户的密码都有很大的帮助,即使他们有权访问数据库和php代码。
这也意味着如果你的用户忘记了他们的密码,就没有办法重新获取它。相反,您编写系统只是将其重置为一个新的随机确定的值,该值会发送给他们,同时强烈鼓励他们在再次登录时更改密码。您甚至可以编写系统,在下次成功登录时强制执行此操作。
我要求密码至少8个字符。理想情况下,它还应该包括数字和特殊字符,但我还没有决定我应该要求这个。也许我应该!
为了防止brute-force攻击,我会在前10分钟内跟踪所有失败的登录。我根据每个IP地址跟踪它们。在3次登录尝试失败后,系统使用sleep()函数延迟对进一步登录尝试的响应。我使用这样的代码块:

$delay = ($failedAttempts - 3);
if ($delay > 0) {
    sleep($delay);
}

imho这比在多次失败后将用户从其帐户中锁定要好得多。它减少了您将获得的客户支持查询的数量,而且对于那些根本记不起自己密码的合法用户来说,它更加优雅。暴力攻击需要每秒多次尝试才能达到任何效率,因此在n = x的基础上延迟会使它们根本无法达到目的。
使用php会话跟踪登录会话。加载网站上的每个页面时,请调用session_start()。(如果您有一个公共的header.php文件,这非常简单。)这使得$_SESSION变量可用。当用户成功登录时,您可以使用此功能存储站点所需的任何信息,以便知道该用户已登录。我通常使用他们的用户id、用户名,也许还有一些特定于站点的其他详细信息。但我这里不包括密码或密码散列。如果黑客以某种方式进入用户的会话数据(存储在服务器上),他们仍然没有机会通过这种方式找到用户的密码。
当发生以下两种情况之一时,就会发生注销:1)删除用户的会话cookie,例如清除浏览器缓存,有时只关闭浏览器窗口,或2)服务器删除其会话数据。当用户在您的站点上按下“注销”按钮时,您可以通过调用session_destroy()来强制后者发生。否则,您可以使会话在一定时间后自动过期。这可能需要调整session.gc_*中的php.ini参数。
如果在初始登录阶段之后您绝对必须知道用户的密码,则可以将其存储在$_SESSION中。只有当您的站点需要ssl连接并且您已经建立了ssl连接,所以没有ssl连接站点就无法工作时,才执行此操作。这样密码就被加密了,因此可以防止packet sniffing。但要知道,如果黑客访问了服务器的会话数据,这是一个安全风险。

关于php - 这是一个适当的登录和注册加密系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11303258/

有关php - 这是一个适当的登录和注册加密系统的更多相关文章

  1. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  2. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  3. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  4. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  5. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  6. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  7. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  8. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  9. arrays - 这是 Ruby 中 Array.fill 方法的错误吗? - 2

    这个问题在这里已经有了答案:Arraysmisbehaving(1个回答)关闭6年前。是否应该这样,即我误解了,还是错误?a=Array.new(3,Array.new(3))a[1].fill('g')=>[["g","g","g"],["g","g","g"],["g","g","g"]]它不应该导致:=>[[nil,nil,nil],["g","g","g"],[nil,nil,nil]]

  10. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下: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列,在这种情况下

随机推荐