关于安全:基于表单的网站认证的最终指南

The definitive guide to form-based website authentication

基于表单的网站身份验证

我们认为,堆栈溢出不仅应该是非常具体的技术问题的资源,而且应该是关于如何解决常见问题变化的一般指南。"基于表单的网站认证"应该是此类实验的一个很好的主题。

它应该包括以下主题:

  • 如何登录
  • 如何注销
  • 如何保持登录状态
  • 管理cookie(包括推荐的设置)
  • SSL/HTTPS加密
  • 如何存储密码
  • 使用秘密问题
  • 忘记用户名/密码功能
  • 使用nonce防止跨站点请求伪造(csrf)
  • OpenID
  • "记住我"复选框
  • 浏览器自动完成用户名和密码
  • 机密URL(由摘要保护的公共URL)
  • 检查密码强度
  • 电子邮件验证
  • 更多关于基于表单的身份验证…

不应包括以下内容:

  • 角色和授权
  • HTTP基本身份验证

请通过以下方式帮助我们:

  • 暗示副标题
  • 提交关于这个主题的好文章
  • 编辑官方答案

  • 第一部分:如何登录

    我们假设您已经知道如何构建一个login+password html表单,该表单将值发布到服务器端的一个脚本以进行身份验证。下面的部分将处理健全的实际授权模式,以及如何避免最常见的安全陷阱。好的。

    去HTTPS还是不去HTTPS?好的。

    除非连接已经是安全的(即,通过使用ssl/tls的https进行隧道连接),否则您的登录表单值将以明文形式发送,允许在浏览器和Web服务器之间的行上窃听的任何人都可以在登录通过时读取登录信息。这种窃听通常是由政府进行的,但一般来说,我们不会处理"拥有"的电线,除非这样说:如果您要保护任何重要的东西,请使用https。好的。

    本质上,在登录期间防止窃听/数据包嗅探的唯一实用方法是使用HTTPS或其他基于证书的加密方案(例如,TLS)或经验证和测试的质询响应方案(例如,基于Diffie-Hellman的SRP)。任何其他方法都很容易被窃听攻击者规避。好的。

    当然,如果你愿意变得有点不切实际,你也可以使用某种形式的双因素认证方案(例如,谷歌认证应用程序、一个物理的"冷战式"代码本或RSA密钥生成器加密狗)。如果应用正确,即使是在不安全的连接上,这也可以工作,但是很难想象开发人员会愿意实现双因素身份验证,而不是SSL。好的。

    (不要)滚动你自己的javascript加密/散列好的。

    考虑到在您的网站上设置一个SSL证书的非零成本和感知到的技术困难,一些开发人员倾向于在浏览器中使用散列或加密方案,以避免通过不安全的连接传递明文登录。好的。

    虽然这是一个高尚的思想,但它本质上是无用的(并且可能是一个安全缺陷),除非它与上述的思想结合在一起——也就是说,要么用强加密保护线路,要么使用一个经过尝试和测试的挑战响应机制(如果你不知道这是什么,只需知道这是最难证明的,最困难的方法之一T到设计,并且最难在数字安全中实现概念)。好的。

    虽然散列密码确实可以有效地防止密码泄露,但它很容易受到重播攻击、中间人攻击/劫持(如果攻击者可以在不安全的HTML页面到达您的浏览器之前向其注入几个字节,他们可以简单地在javascript中注释散列),或暴力攻击。(因为您将用户名、salt和哈希密码都交给攻击者)。好的。

    反人类船长好的。

    是用来验证码是一类特异性thwart /蛮力字典攻击:自动试错和没有人类操作员。有没有怀疑这是一个真正的威胁,然而,当你处理它的方式seamlessly不需要验证码,登录在服务器端的具体设计方案-内节流式我们讨论这些以后。

    验证码的实现是不知道谁创造了你;他们不是人力可解,大多数人是真的ineffective打击僵尸,他们都是对第三世界ineffective廉价的实验室(根据OWASP的血汗工厂,目前的测试通过率是12 500美元),和一些实现的技术在一些可能是非法的湖国家(OWASP认证作弊表)。如果你必须使用一个验证码,验证码的使用谷歌,因为它是硬的OCR定义(因为它已经使用OCR错误图书扫描)和强硬的和用户友好的。

    就我个人而言,我没有找到,他们只使用,和使用作为最后当一用户登录失败安切洛蒂作为内节流式是maxed时报和延迟退房。这将是可接受的清洁很少发生,它strengthens漫游系统作为一个整体。

    保密码登录/核查

    这可能是普通的知识,毕竟我们的注册用户数据泄密、黑客和publicized我们见过在最近几年,但它是说:不要在你的数据库中存储的密码cleartext。用户数据库是routinely泄露或gleaned通黑,SQL注入,如果你储存的原始文件,这是密码,登录即时游戏为您的安全。

    所以如果你不能存储的密码,它是你如何检查登录密码登录+结合的形式张贴在正确的是?答案是使用密钥的散列函数的推导。每当一个新的用户创建的密码,或是把你的密码和运行它通过KDF,如argon2,bcrypt,scrypt或pbkdf2,转折的cleartext密码("correcthorsebatterystaple")到一个长期的前瞻性,随机字符串,这是很多更安全的存储在你的数据库。验证登录到相同的哈希函数,你在运行时传递进来的密码,这是造成在盐和比较哈希值存储在字符串到您的数据库。argon2 bcrypt和盐,scrypt商店已经在哈希。在这篇文章中sec.stackexchange退房的更多详细信息。

    原因一是盐是用散列本身是不足够的-你想添加一个所谓的"盐",保护对彩虹哈希表。a盐有效地防止密码完全匹配从两个相同的哈希值被存储为防止被扫描整个数据库,运行在一个四attacker一直就这样在事后来劝告正在执行一个密码攻击。

    密码存储不应使用加密散列,因为用户选择的密码不够强(即通常不包含足够的熵),具有散列访问权限的攻击者可以在相对短的时间内完成密码猜测攻击。这就是使用kdf的原因——这些有效地"拉伸密钥",这意味着攻击者所做的每一个密码猜测都会导致哈希算法重复多次,例如10000次,这会导致攻击者猜测密码的速度减慢10000倍。好的。

    会话数据-"您以spiderman69登录"好的。

    一旦服务器根据用户数据库验证了登录名和密码并找到匹配项,系统就需要一种方法来记住浏览器已经过身份验证。这个事实应该只存储在会话数据的服务器端。好的。

    If you are unfamiliar with session data, here's how it works: A single randomly-generated string is stored in an expiring cookie and used to reference a collection of data - the session data - which is stored on the server. If you are using an MVC framework, this is undoubtedly handled already.

    Ok.

    如果可能,确保会话cookie在发送到浏览器时设置了安全和仅HTTP标志。httponly标志提供了一些保护,防止通过XSS攻击读取cookie。安全标志确保cookie只能通过https发送回,因此可以防止网络嗅探攻击。cookie的值不应是可预测的。如果出现引用不存在会话的cookie,则应立即替换其值以防止会话固定。好的。第二部分:如何保持登录-臭名昭著的"记住我"复选框

    持久登录cookie("记住我"功能)是一个危险区域;一方面,当用户了解如何处理它们时,它们与传统登录完全一样安全;另一方面,在粗心的用户手中,它们是一个巨大的安全风险,粗心的用户可能会在公共计算机上使用它们,而忘记注销,他们可能不会现在,什么是浏览器cookie,或者如何删除它们。好的。

    就我个人而言,我喜欢经常访问的网站的持续登录,但我知道如何安全地处理它们。如果您确信您的用户也知道这一点,那么您就可以用良心清白的持久登录。如果不是,那么你可以接受这样一种理念:如果用户不小心使用了他们的登录凭证,那么一旦他们被黑客攻击,他们就会受到攻击。这也不像我们去用户的家里,撕掉所有的facepalm诱导贴,上面写着他们在显示器边缘排列的密码。好的。

    当然,有些系统负担不起任何帐户被黑客攻击;对于此类系统,您无法证明持久登录是正确的。好的。

    如果您确实决定实现持久登录cookie,那么可以这样做:好的。

  • 首先,花些时间阅读Paragon Initiative关于这个主题的文章。你需要把一堆元素弄对,这篇文章对每一个都做了很好的解释。好的。

  • 为了重申最常见的陷阱之一,不要将持久登录cookie(token)存储在数据库中,只存储其中的一个散列值!登录令牌相当于密码,因此如果攻击者掌握了您的数据库,他们可以使用令牌登录到任何帐户,就像他们是明文登录密码组合一样。因此,在存储持久登录令牌时,请使用散列(根据https://security.stackexchange.com/a/63438/5002,弱散列就可以了)。好的。

  • 第三部分:使用秘密问题

    不要执行"秘密问题"。"秘密问题"功能是一种安全反模式。从"必须读"列表的链接4中读取纸张。你可以问莎拉佩林关于那个,在她的雅虎之后!在前一次总统竞选中,电子邮件帐户遭到黑客攻击,因为她对安全问题的回答是…"瓦西拉高中"!好的。

    即使有用户指定的问题,大多数用户也很可能选择:好的。

    • 一个"标准"的秘密问题,比如母亲的娘家姓或最喜欢的宠物。好的。

    • 任何人都可以从他们的博客、LinkedIn个人资料或类似资料中提取到一个简单的琐事。好的。

    • 任何比猜测密码更容易回答的问题。对于任何一个像样的密码来说,这是你能想象到的每一个问题好的。

    总之,安全问题本质上是不安全的,几乎在所有形式和变化中都是不安全的,不应以任何理由将其用于身份验证方案。好的。

    安全问题甚至存在于野外的真正原因是,它们方便地节省了一些无法访问电子邮件以访问重新激活代码的用户的支持呼叫成本。这是以牺牲安全和莎拉·佩林的名誉为代价的。值得的?大概不会。好的。第四部分:忘记密码功能

    我已经提到了为什么你不应该使用安全问题来处理忘记/丢失的用户密码;也没有说你不应该向用户发送他们的实际密码。在这个领域,至少还有两个太常见的陷阱需要避免:好的。

  • 不要将忘记的密码重置为自动生成的强密码-这种密码众所周知很难记住,这意味着用户必须更改或写下来-例如,在显示器边缘的亮黄色贴纸上。不要设置新密码,只需让用户立即选择一个新密码-这是他们无论如何都想做的。(这可能是一个例外,如果用户普遍使用密码管理器来存储/管理通常不写下来就无法记住的密码)。好的。

  • 总是散列数据库中丢失的密码代码/令牌。同样,此代码是另一个等价密码的示例,因此必须对其进行哈希处理,以防攻击者接触到您的数据库。当请求丢失的密码时,将明文代码发送到用户的电子邮件地址,然后散列它,将散列保存在数据库中——并丢弃原始密码。就像密码或持久登录令牌。好的。

  • 最后一点注意:始终确保用于输入"丢失密码代码"的界面至少与登录表单本身一样安全,否则攻击者只需使用该界面获取访问权。确保生成非常长的"丢失密码"(例如,16个区分大小写的字母数字字符)是一个很好的开始,但是考虑添加与登录表单本身相同的限制方案。好的。第五部分:密码强度检查

    首先,您需要阅读这篇小文章来进行实际检查:500个最常见的密码好的。

    好吧,所以这个列表可能不是任何系统中最常见密码的规范列表,但它很好地说明了当没有强制执行的策略时,人们选择密码的能力有多差。另外,当你将它与最近被盗密码的公开分析相比较时,这个列表看起来非常接近。好的。

    所以:由于没有最低的密码强度要求,2%的用户使用前20个最常见的密码之一。意思是:如果攻击者只有20次尝试,你网站上的50个账户中就有1个会被破解。好的。

    要阻止这种情况,需要计算密码的熵,然后应用阈值。国家标准与技术研究所(NIST)特别出版物800-63有一套非常好的建议。当结合字典和键盘布局分析(例如,"qwertyuiop"是一个错误的密码)时,可以在18位熵的水平上拒绝99%的错误选择的密码。简单计算密码强度并向用户显示视觉强度计是好的,但不够。除非强制执行,否则很多用户很可能会忽略它。好的。

    为了刷新高熵密码的用户友好性,强烈推荐Randall Munroe的密码强度xkcd。好的。第六部分:更多-或:防止快速登录尝试

    首先,看看这些数字:密码恢复速度-密码的有效期有多长好的。

    如果您没有时间浏览该链接中的表,下面是它们的列表:好的。

  • 破解一个弱密码几乎不需要时间,即使你是用算盘破解它。好的。

  • 如果不区分大小写,则几乎不需要花费时间破解字母数字9字符密码。好的。

  • 如果密码长度小于8个字符,几乎不需要花时间破解复杂的符号、字母和数字、大小写密码(台式电脑可以在几天甚至几小时内搜索7个字符)。好的。

  • 但是,如果您限制为每秒尝试一次,那么破解一个6个字符的密码需要花费大量的时间!好的。

  • 那么我们能从这些数字中学到什么呢?好吧,很多,但我们可以把重点放在最重要的部分:防止大量快速启动的连续登录尝试(即蛮力攻击)并没有那么困难。但是,正确地预防并不像看上去那么容易。好的。

    一般来说,您有三种选择都能有效地抵御蛮力攻击(和字典攻击,但由于您已经采用了强密码策略,因此它们不应该是问题):好的。

    • 在N次失败的尝试之后出示一个验证码(令人讨厌,而且通常无效——但我在这里重复我自己)好的。

    • 尝试n次失败后锁定帐户并要求电子邮件验证(这是等待发生的DoS攻击)好的。

    • 最后,登录限制:也就是说,在n次失败的尝试之后设置尝试之间的时间延迟(是的,DoS攻击仍然可能,但至少它们的可能性要小得多,而且实现起来要复杂得多)。好的。

    最佳实践1:随着失败尝试次数的增加而增加的短时间延迟,例如:好的。

    • 1次尝试失败=无延迟
    • 2次失败的尝试=2秒延迟
    • 3次失败的尝试=4秒延迟
    • 4次失败的尝试=8秒延迟
    • 5次失败的尝试=16秒延迟
    • 等。

    DOS攻击这个方案是非常不切实际的,因为产生的锁定时间略大于前一个锁定时间的总和。好的。

    To clarify: The delay is not a delay before returning the response to the browser. It is more like a timeout or refractory period during which login attempts to a specific account or from a specific IP address will not be accepted or evaluated at all. That is, correct credentials will not return in a successful login, and incorrect credentials will not trigger a delay increase.

    Ok.

    最佳实践2:在n次失败尝试后生效的中等长度时间延迟,例如:好的。

    • 1-4次失败的尝试=无延迟
    • 5次失败的尝试=15-30分钟延迟

    DOS攻击这个计划是非常不切实际的,但肯定是可行的。另外,值得注意的是,这种长时间的延迟对于合法用户来说是非常烦人的。健忘的用户会不喜欢你。好的。

    最佳实践3:将这两种方法结合在一起-在n次失败尝试后,固定的短时间延迟生效,例如:好的。

    • 1-4次失败的尝试=无延迟
    • 5次以上失败的尝试=20秒延迟

    或者,具有固定上限的增加延迟,例如:好的。

    • 1次失败的尝试=5秒延迟
    • 2次失败的尝试=15秒延迟
    • 3次以上失败的尝试=45秒延迟

    该最终方案取自OWASP最佳实践建议(必须阅读的列表中的链接1),应被视为最佳实践,即使该方案确实存在限制性。好的。

    As a rule of thumb, however, I would say: the stronger your password policy is, the less you have to bug users with delays. If you require strong (case-sensitive alphanumerics + required numbers and symbols) 9+ character passwords, you could give the users 2-4 non-delayed password attempts before activating the throttling.

    Ok.

    DOS攻击这个最终登录限制方案是非常不切实际的。最后一点是,始终允许持久(cookie)登录(和/或验证了验证码的登录表单)通过,这样合法用户在攻击过程中甚至不会被延迟。这样,非常不切实际的DoS攻击就变成了非常不切实际的攻击。好的。

    此外,对管理帐户进行更积极的限制是有意义的,因为这些是最有吸引力的入口点好的。第七部分:分布式暴力攻击

    和旁白一样,更高级的攻击者会试图通过"散布他们的活动"来绕过登录限制:好的。

    • 在僵尸网络上分发尝试以防止IP地址标记好的。

    • 他们不会选择一个用户并尝试50000个最常见的密码(因为我们的限制,他们不能这样做),而是选择最常见的密码并针对50000个用户进行尝试。这样一来,他们不仅可以绕过诸如captchas和登录限制之类的最大尝试次数,而且成功的机会也会增加,因为数字1最常见的密码比数字49.995更可能出现。好的。

    • 间隔每个用户帐户的登录请求,例如间隔30秒,以潜入雷达下好的。

    在这里,最佳实践是记录失败登录的数量、系统范围,并使用站点错误登录频率的运行平均值作为对所有用户施加的上限的基础。好的。

    过于抽象?让我换个说法:好的。

    假设你的网站在过去的3个月里平均每天有120次错误登录。使用这个(运行平均值),您的系统可能会将全局限制设置为3倍,即24小时内360次失败的尝试。然后,如果所有帐户的失败尝试总数在一天内超过该数字(或者更好的方法是,监视加速率并在计算的阈值上触发),它将激活系统范围内的登录限制-这意味着所有用户的延迟都很短(但cookie登录和/或备份captcha登录除外)。好的。

    我还发布了一个更详细的问题,并讨论了如何避免分布式蛮力攻击中的棘手陷阱。好的。第八部分:双因素认证和认证提供者

    无论是通过漏洞攻击、密码被写下来并丢失、带有密钥的笔记本电脑被偷,还是用户登录到网络钓鱼网站,都可能破坏凭据。使用双因素认证可以进一步保护登录,该认证使用带外因素,例如从电话呼叫、短信、应用程序或加密狗接收到的一次性代码。一些提供者提供双因素认证服务。好的。

    身份验证可以完全委托给一个登录服务,在该服务中,另一个提供者负责收集凭证。这就把问题推给了一个可信的第三方。谷歌和Twitter都提供基于标准的SSO服务,而Facebook也提供类似的专有解决方案。好的。有关Web身份验证的必读链接

  • OWASP认证指南/OWASP认证备忘表
  • 网上客户认证的注意事项(麻省理工学院的研究论文非常易读)
  • 维基百科:HTTP cookie
  • 回退认证的个人知识问题:Facebook时代的安全问题(非常易读的伯克利研究论文)
  • 好啊。


    最终条款正在发送凭据

    唯一可行的100%安全地发送凭证的方法是使用SSL。使用javascript散列密码是不安全的。客户端密码散列的常见缺陷:好的。

    • 如果客户机和服务器之间的连接未加密,那么您所做的一切都容易受到中间人攻击。攻击者可以替换传入的javascript来破坏散列或将所有凭证发送到其服务器,他们可以监听客户端响应并完全模拟用户等。具有可信证书颁发机构的SSL旨在防止MITM攻击。
    • 如果您不在服务器上做额外的、冗余的工作,服务器接收的哈希密码就不那么安全。

    还有另一种称为srp的安全方法,但它已获得专利(尽管它是免费许可的),而且几乎没有好的实现可用。好的。存储口令

    不要将密码以明文形式存储在数据库中。即使你不关心你自己网站的安全也不行。假设您的一些用户将重用其在线银行帐户的密码。所以,存储哈希密码,并扔掉原始密码。并确保密码不会出现在访问日志或应用程序日志中。OWASP建议使用argon2作为新应用程序的首选。如果不可用,则应使用pbkdf2或scrypt。最后,如果以上都不可用,请使用bcrypt。好的。

    散列本身也是不安全的。例如,相同的密码意味着相同的哈希——这使得哈希查找表成为同时破解大量密码的有效方法。相反,把盐腌的土豆泥储存起来。salt是在散列之前附加到密码的字符串-每个用户使用不同的(随机)salt。salt是一个公共值,因此可以将它们与哈希一起存储在数据库中。更多信息请参见此处。好的。

    这意味着您不能向用户发送他们忘记的密码(因为您只有散列值)。除非您已经验证了用户身份,否则不要重置用户的密码(用户必须证明他们能够读取发送到存储(和验证)电子邮件地址的电子邮件。)好的。安全问题

    安全问题是不安全的-避免使用它们。为什么?任何安全问题都可以,密码更好。阅读第三部分:使用@jens roland中的秘密问题在此wiki中回答。好的。会话cookie

    用户登录后,服务器向用户发送会话cookie。服务器可以从cookie中检索用户名或ID,但没有其他人可以生成这样的cookie(要解释机制)。好的。

    cookies可以被劫持:它们只有和客户机的其他机器和其他通信一样安全。它们可以从磁盘读取,在网络流量中嗅探,被跨站点脚本攻击解除,从中毒的DNS进行网络钓鱼,因此客户端将其cookie发送到错误的服务器。不要发送持久的cookie。cookie应该在客户端会话结束时过期(浏览器关闭或离开您的域)。好的。

    如果要自动登录用户,可以设置持久cookie,但它应与完整会话cookie不同。您可以设置一个额外的标志,用户已经自动登录,并且需要为敏感操作实际登录。这一点很受购物网站的欢迎,这些网站希望为您提供无缝、个性化的购物体验,但仍然保护您的财务细节。例如,当你返回亚马逊时,他们会给你显示一个看起来你已经登录的页面,但是当你去下订单(或者更改你的送货地址、信用卡等)时,他们会要求你确认密码。好的。

    另一方面,银行和信用卡等金融网站只有敏感数据,不应允许自动登录或低安全模式。好的。外部资源列表

    • Web上客户端身份验证的注意事项(pdf)21页的学术文章,有很多好的提示。
    • 询问YC:用户身份验证的最佳实践论坛主题讨论
    • 您可能存储的密码不正确关于存储密码的介绍性文章
    • 讨论:编写恐怖代码:您可能错误地存储了密码论坛讨论了一篇恐怖文章的编码。
    • 不要将密码存储在数据库中!关于在数据库中存储密码的另一个警告。
    • 密码破解维基百科关于几种密码散列方案弱点的文章。
    • 彩虹表足够了:关于安全密码方案你需要知道什么讨论彩虹表以及如何防御它们,以及如何抵御其他线程。包括广泛的讨论。

    好啊。


    首先,强烈警告说,这个答案不适合这个确切的问题。这绝对不是最好的答案!

    我将继续讨论Mozilla提出的browserid(或者更准确地说,是经过验证的电子邮件协议),本着在未来找到更好的身份验证方法的升级路径的精神。

    我将这样总结:

  • Mozilla是一个非营利性组织,它的价值观与找到解决这个问题的好方法很一致。
  • 今天的现实是,大多数网站使用基于表单的身份验证
  • 基于表单的身份验证有一个很大的缺点,这增加了网络钓鱼的风险。要求用户将敏感信息输入由远程实体控制的区域,而不是由其用户代理(浏览器)控制的区域。
  • 由于浏览器是隐式信任的(用户代理的整个思想是代表用户进行操作),因此它们可以帮助改善这种情况。
  • 阻碍进度的主要因素是部署死锁。解决方案必须分解为步骤,这些步骤本身就提供了一些增量收益。
  • 表示内置于互联网基础设施中的身份的最简单的分散方法是域名。
  • 作为表示身份的第二级,每个域管理自己的一组帐户。
  • 形式"account@域"简洁,并由各种协议和URI方案支持。当然,这样的标识符是最普遍公认的电子邮件地址。
  • 电子邮件提供商已经是事实上的主要在线身份提供商。当前密码重置流通常允许您控制一个帐户,如果您可以证明您控制了该帐户的相关电子邮件地址。
  • 已验证的电子邮件协议被提议提供一种基于公钥加密的安全方法,用于简化向域B证明您在域A上拥有帐户的过程。
  • 对于不支持已验证电子邮件协议的浏览器(目前所有浏览器),Mozilla提供了一个填充程序,该填充程序在客户端JavaScript代码中实现了该协议。
  • 对于不支持已验证电子邮件协议的电子邮件服务,该协议允许第三方充当受信任的中介,断言他们已经验证了用户对帐户的所有权。不希望有大量此类第三方;此功能仅用于允许升级路径,电子邮件服务更倾向于自己提供这些断言。
  • Mozilla提供他们自己的服务,使其像这样一个受信任的第三方。实现经过验证的电子邮件协议的服务提供商(即依赖方)可以选择是否信任Mozilla的断言。Mozilla的服务使用传统的发送带有确认链接的电子邮件的方式来验证用户的帐户所有权。
  • 当然,除了他们可能希望提供的任何其他身份验证方法之外,服务提供者还可以提供此协议作为选项。
  • 这里寻求的一个巨大的用户界面好处是"身份选择器"。当用户访问一个站点并选择进行身份验证时,他们的浏览器会向他们显示一组电子邮件地址("个人"、"工作"、"政治活动"等),这些地址可用于向该站点标识自己。
  • 作为这项工作的一部分,另一个巨大的用户界面好处是帮助浏览器了解更多关于用户会话的信息——他们目前主要是以谁的身份登录的——因此它可能会在浏览器的Chrome中显示这些信息。
  • 由于该系统的分布式特性,它避免了锁定到Facebook、Twitter、Google等主要网站。任何个人都可以拥有自己的域,因此可以充当自己的身份提供者。
  • 这并不是严格的"基于表单的网站认证"。但是,这是一项努力,从当前基于表单的身份验证的规范过渡到更安全的规范:浏览器支持的身份验证。


    我只是觉得我会分享这个解决方案,我发现它工作得很好。

    我称之为虚拟场(尽管我没有发明这个,所以不要相信我)。

    简而言之:您只需将它插入到您的

    中,并在验证时检查它是否为空:

    1
    <input type="text" name="email" style="display:none" />

    诀窍是愚弄一个机器人,让它认为必须将数据插入一个必需的字段,这就是为什么我将输入命名为"email"。如果您已经有了一个名为email的字段,那么您应该尝试将这个虚拟字段命名为"company"、"phone"或"emailaddress"。只需选择一些你不需要的,听起来像人们通常会觉得合乎逻辑的东西来填充到一个Web表单中。现在,使用css或javascript/jquery隐藏input字段-无论什么最适合您-只需不要将输入type设置为hidden,否则bot就不会爱上它。

    在验证表单(客户端或服务器端)时,请检查是否已填充了虚拟字段,以确定它是由人类还是机器人发送的。

    例子:

    如果是人:用户将看不到虚拟字段(在我的例子中称为"email"),也不会尝试填充它。因此,在发送表单时,虚拟字段的值应该仍然为空。

    对于bot:bot将看到一个类型为text的字段和一个名称email的字段(或您称之为的任何字段),并在逻辑上尝试用适当的数据填充它。它不关心您是否用一些花哨的CSS设置输入表单的样式,Web开发人员总是这样做。不管虚拟字段中的值是什么,只要它大于0个字符,我们就不在乎了。

    我在一本留言簿上结合了验证码使用了这种方法,从那以后我就再也没有看到过一篇垃圾邮件。我以前只使用过一个验证码的解决方案,但最终每小时都会收到大约五封垃圾邮件。在表单中添加虚拟字段已停止(至少直到现在)所有垃圾邮件的显示。

    我相信这也可以和登录/验证表单一起使用。

    警告:当然,这种方法不是100%万无一失的。bots可以编程为忽略应用了display:none样式的输入字段。您还必须考虑使用某种形式的自动完成功能的人(就像大多数浏览器都内置了!)自动填充所有表单域。他们也可以选择一个虚拟的领域。

    您也可以通过让虚拟字段在屏幕边界之外可见来稍微改变这一点,但这完全取决于您。

    要有创造力!


    我不认为上面的答案是"错误的",但是有很多认证领域没有涉及到(或者更确切地说,重点是"如何实现cookie会话",而不是"有什么选择和权衡"。

    我建议的编辑/答案是

    • 问题更多地在于帐户设置而不是密码检查。
    • 使用双因素认证比使用更巧妙的密码加密方法更安全。
    • 不要试图实现您自己的登录表单或密码的数据库存储,除非存储的数据在帐户创建和自我生成时没有价值(即,像Facebook、Flickr等Web2.0样式)。

    • 摘要式身份验证是所有主要浏览器和服务器都支持的基于标准的方法,即使通过安全通道也不会发送密码。

    这避免了任何需要"会话"或cookie的情况,因为浏览器本身每次都会重新加密通信。它是最"轻量级"的开发方法。

    但是,我不建议这样做,除了公共的、低价值的服务。这是上面其他一些答案的一个问题-不要尝试重新实现服务器端身份验证机制-这个问题已经解决,并且大多数主要浏览器都支持这个问题。不要使用cookies。不要将任何内容存储在您自己的手动滚动数据库中。只需根据请求询问请求是否经过身份验证。其他一切都应该由配置和第三方可信软件支持。

    所以…

    首先,我们将最初创建的帐户(使用密码)与随后重新检查密码混淆在一起。如果我是Flickr,并且是第一次创建您的站点,那么新用户可以访问零值(空白Web空间)。我真的不在乎创建帐户的人是否在他们的名字上撒了谎。如果我正在创建医院内部网/外联网的帐户,其价值在于所有病历,因此我确实关心帐户创建者的身份(*)。

    这是非常困难的部分。唯一体面的解决办法是建立信任网。例如,你以医生的身份加入医院。您可以创建一个包含照片、护照号和公钥的网页,然后用私钥散列它们。然后您访问医院,系统管理员查看您的护照,查看照片是否与您匹配,然后使用医院私钥散列网页/照片散列。从现在起,我们可以安全地交换密钥和令牌。任何信任医院的人都可以(顺便说一句,这里有秘密酱汁)。系统管理员还可以为您提供RSA加密狗或其他双因素身份验证。

    但这很麻烦,而且不是很容易实现Web2.0。但是,它是创建新帐户的唯一安全方法,这些帐户可以访问非自我创建的有价值的信息。

  • kerberos和spnego-具有受信任的第三方的单一登录机制-基本上是用户针对受信任的第三方进行验证。(注意,这在任何方面都不是不可信任的OAuth)

  • SRP-一种没有可信第三方的智能密码认证。但现在我们进入了"使用双因素身份验证更安全,即使代价更高"的领域。

  • SSL客户端-为客户端提供一个公钥证书(在所有主要浏览器中都支持),但会对客户端计算机的安全性提出问题。

  • 最后,这是一种权衡——安全漏洞的代价与实现更安全方法的代价是什么?有一天,我们可能会看到一个被广泛接受的合适的pki,因此不再有自己的滚动身份验证表单和数据库。有一天。。。


    散列时,不要使用快速散列算法,如MD5(存在许多硬件实现)。使用类似sha-512的东西。对于密码,较慢的哈希值更好。

    创建哈希的速度越快,任何蛮力检查器都可以工作得越快。因此,较慢的哈希将减慢暴力强制。一个缓慢的哈希算法将使暴力强制更长的密码(8位以上)变得不切实际。


    关于实际密码强度估计的一篇好文章是:

    Dropbox技术博客»;博客存档»;zxcvbn:真实的密码强度估计


    我最喜欢的认证系统规则是:使用密码,而不是密码。容易记住,难破解。更多信息:编码恐怖:密码与密码短语


    我想添加一个我使用过的建议,基于深度防御。您不需要像普通用户一样拥有相同的管理员认证系统。您可以在一个单独的URL上有一个单独的登录表单,为将授予高权限的请求执行单独的代码。这一个可以做出选择,这将是一个总痛苦的常规用户。其中一个我曾经使用过的是,为管理员访问而对登录URL进行加密,并通过电子邮件将新的URL发送给管理员。立即停止任何暴力攻击,因为您的新URL可能是任意困难的(非常长的随机字符串),但您的管理员用户唯一的不便是在他们的电子邮件中跟踪链接。攻击者再也不知道该发往何处。


    我不知道作为回答还是作为评论来回答是最好的。我选择了第一个选项。

    关于poing第四部分:第一个答案中忘记的密码功能,我将对定时攻击做一点说明。

    在"记住您的密码"表单中,攻击者可能会检查电子邮件的完整列表并检测注册到系统的电子邮件(请参阅下面的链接)。

    对于忘记密码的表单,我想补充一点,使用延迟函数在成功查询和未成功查询之间等时间是一个好主意。

    https://crypto.stanford.edu/~dabo/papers/webtiming.pdf网站


    我想补充一个非常重要的意见:

    • "在公司内部的网络设置中,"大多数(如果不是全部)上述可能不适用!

    许多公司部署"仅供内部使用"的网站,这些网站实际上是通过URL实现的"公司应用程序"。这些URL只能(假设是…)在"公司的内部网络"中解决(该网络神奇地包括所有连接到VPN的"道路战士")。

    当用户被尽职地连接到上述网络时,他们的身份("认证")已经"确定地知道",以及他们做某些事情的许可("授权")…比如……"访问此网站。"

    这个"身份验证+授权"服务可以由几种不同的技术提供,例如LDAP(Microsoft OpenDirectory)或Kerberos。

    从您的角度来看,您只需知道:任何合法结束在您的网站的人都必须有[一个环境变量神奇地包含…]一个"令牌"。(即,没有这样的令牌必须是404 Not Found的直接理由。)

    令牌的价值对您没有意义,但是,如果需要,"适当的手段存在",通过它您的网站可以"[权威地]问一个知道的人(LDAP…等)"关于任何和每一个(!)你可能有的问题。换句话说,你没有利用任何"本土逻辑",相反,你询问权威并暗中相信它的裁决。

    嗯…这是从"狂野而混乱的互联网"转变过来的一个心理转变。


    使用OpenID连接或用户管理的访问。

    因为没有什么比不做更有效的了。