没有HTTPS登录,如何安全?

时间:2010-02-25 18:43:18

标签: php ajax security encryption cryptography

对于Web应用程序,当HTTPS不可用作安全措施时,是否仍然可以使登录有点安全? E.g:

  • Tokenize登录,难以重复攻击吗?
  • 以某种方式加密来自HTML密码字段的已发送密码?

特别是我正在使用CakePHP和AJAX POST调用来触发身份验证(包括提供的用户名和密码)。

问题更新:

  • HTTPS不可用。期。如果您不喜欢这种情况,请将其视为一个理论问题。
  • 没有明确的要求,你有现实生活中提供的HTTP,PHP和浏览器(cookies,JavaScript等)(没有神奇的RSA二进制文件,PGP插件)。
  • 问题是,什么是最好的,你可以用这个的情况,这比发送密码明文更好。了解每种此类解决方案的缺点是一个优势。
  • 欢迎任何比普通密码更好的改进。我们的目标不是100%l33tG0Dhx0r-proff解决方案。难以破解比破解复杂更好,这比揭露密码的琐碎嗅探要好。

20 个答案:

答案 0 :(得分:76)

HTTPS在维护网站和浏览器之间的安全连接方面绝对至关重要Public wifi networks put users at risk,如果使用正确, HTTPS是唯一可以保护用户帐户免受this vulnerability影响的工具

如果您的主机不支持HTTPS,则可以使用Cloudflare Universal SSL之类的服务来确保所有浏览器都使用HTTPS 连接到您的网站,即使您的服务器不支持SSL / TLS 。 Cloudflare与您的网站之间的连接仍然不受保护,但此Cloudflare服务旨在保护用户免受公共wifi网络上的威胁。从渗透测试人员的角度来看,不提供HTTPS是非常可疑的,如果您没有提供交付流量的基本安全要求,那么您还缺少哪些其他安全要求?可以使用Let's EncryptStart SSL免费获取HTTPS证书,没有正当理由不支持HTTPS。

HTTPS至关重要,因为它不仅仅是“加密密码”。另一个重要的角色是它应该阻止用户登录冒充真实服务器的恶意服务器。使用系统单独保护密码仍违反OWASP A9 - Insufficient Transport Layer Protection,因为您仍然会以纯文本形式发送会话凭据,这是攻击者的全部需求(Firesheep)。

  1. JavaScript-based cryptography cannot be used to construct a secure transport layer

  2. “Tokenize登录”:如果攻击者正在嗅探 流量,他们将使用纯文本用户名/密码然后 他们可以使用这些新凭据登录。 (重播攻击)

  3. “以某种方式加密传输的密码”:此人登录后 攻击者可以嗅探流量以获得有效的会话ID (cookie)然后只使用它而不是登录。如果 整个会话都受SSL / TLS保护,那么这不是问题。

  4. 还有其他更复杂的攻击会影响此系统和我们当前的SSL基础架构。 SSLStrip攻击更详细。我强烈推荐watching Moxie Marlinspike's Blackhat 2009 talk,这会导致HTTP-Strict-Transport-Security standard

答案 1 :(得分:16)

由于您无法在Web服务器上执行SSL,并且您不是安全专家,因此请查找可以使用的现有安全身份验证服务,并让他们同时处理SSL和处理凭据的复杂性。

特别是,我建议您使用免费的第三方身份验证服务,例如OpenID。他们有PHP的库,包括CakePHP的库。


编辑:(关于风险)

虽然使用第三方安全身份验证服务(使用HTTPS本身)可以缓解在不使用HTTPS(在您的服务器上)进行身份验证的问题,但它并不能完全消除攻击的可能性。

最常见的两种攻击是重播攻击和会话劫持,攻击者可以在以后重新使用正版登录会话令牌,或者使用一个有效的会话令牌,用于自己的恶意目的。

可以通过使会话令牌到期来缓解重放攻击,并且最好使用nonce来阻止会话重放并降低会话劫持的风险。使用nonce,合法会话在成功被劫持时会生成错误,因为nonce已过期(已使用),因此他们自己的会话不再有效。

如果在向服务器传输会话令牌时无法使用HTTPS加密会话令牌,则无法完全阻止主动攻击,例如会话劫持 man-in-the-中间攻击。在某些情况下,可能是可以接受的,例如用于非商业用途的用户群较少的网站。

答案 2 :(得分:14)

简短的回答是,如果没有SSL端点到端点加密,就不可能安全地进行...

其中一个主要原因是您无法在浏览器中执行安全加密。请参阅this reference - Javascript Cryptography Considered Harmful

此外,您无法确定凭据的来源确实是您正在与之交谈的人。这意味着没有SSL就绝对没有办法确保没有Man-In-The-Middle Attack继续进行。

所以不,你不能这样做。

此外,甚至不要尝试。获取SSL。你可以获得免费证书。主持人通常会为您提供每月几$$$的专用IP。如果您真的关心安全性,那么您至少会使用具有专用IP地址的VM。

即使尝试这种情况,最好是Security Through Obscurity,最糟糕的是什么。 SSL是一个已解决的问题。为什么不使用该解决方案。安全性无法猜测。使用适当的技术。不要试图发明自己的。它不会起作用......

答案 3 :(得分:13)

正如您所建议的,您可以在每次创建页面时生成唯一标记。需要使用表单数据发送相同的令牌,并且无法重复使用。如果您可以依赖用户启用它,您还可以使用JavaScript对其进行哈希,从而保护密码的安全。

然而,这种方案仍然不安全。攻击者仍然可以看到一切都在线上。他们可以拦截令牌并在用户发送之前向您发送回复。或者他们可以等待某人登录,窃取该人的凭据(因为他们通过网络发送),然后稍后发出他们自己的登录请求。

底线 - 您需要使用HTTPS来保证网站的安全。

答案 4 :(得分:6)

您可以使用大多数浏览器都支持的HTTP Digest身份验证,并且不会通过网络明确发送密码。

缺点是broswer显示的丑陋登录框。如果你坚持使用表单,那么你可以在表单authnetication中实现与HTTP Digest完全相同的协议:发送包含领域和挑战的隐藏字段,并让客户端在JavaScript中添加nonce并计算摘要。通过这种方式,您将使用众所周知且经过验证的排除协议,而不是使用自己的协议。

HTTP摘要只需要哈希操作。

答案 5 :(得分:6)

您可以使用Javascript加密密码并在服务器上解密。

我建议在服务器上生成一个RSA密钥对,将公钥和定时盐一起发送到浏览器,然后使用Javascript中的公钥加密密码,加上盐。

您可以在Javascript here

中找到RSA实施

您应该在身份验证Cookie中包含IP地址和整个X-FORWARDED-FOR hedaer,以防止代理服务器后面的cookie被盗。

如果您正在处理敏感数据,则可以生成随机AES key in Javascript,然后将其与使用RSA加密的密码一起发送到服务器。
然后,您可以使整个应用程序从单个页面使用加密的AJAX请求,而根本不使用auth cookie。

请注意,如果没有SSL,就无法防范活跃的中间人攻击。活跃的攻击者可以使用自己的代理完全替换您的站点,并且没有任何方法可以防御它。 (因为没有任何已知的好代码)

答案 6 :(得分:2)

HTTP Digest Authentication怎么样?它在将MD5-hashing用户名,密码和nonce(以及其他内容)发送到服务器之前提供安全性。 MD5并不是真正安全,但它是使用HTTP实现简单安全性的好方法。

当然,这并不能阻止黑客更改消息......但它可以保护您的密码。

答案 7 :(得分:2)

HTTPS有许多用例,其中大部分用于防御中间人攻击。任何有黑客心态的人都会不寒而栗地告诉你除了既定的方法之外别无他法。事实是,仅仅因为您使用TLS(现代HTTPS使用的标准),并不意味着您正在使用它。此外,仅使用TLS并不能阻止某人利用已知的弱点。正如您可能正在寻找创造性的方法来保护您的数据一样,有些人正在寻找创造性的方法来利用您的安全措施。

那么,该怎么办?

首先,如果您要放弃TLS,了解它的工作原理会很有帮助。这完全是握手。

  

一旦客户端和服务器同意使用TLS,他们就会协商一个   通过握手程序进行有状态连接。[7]在这   握手,客户端和服务器就各种参数达成一致   建立连接的安全性:

     
      
  • 当客户端连接到启用了TLS的服务器时,握手开始   请求安全连接并显示支持的密码列表   套件(密码和散列函数)。
  •   
  • 从此列表中,服务器选择   一个密码和哈希函数,它也支持并通知   客户的决定。
  •   
  • 服务器发回其身份证明   数字证书的形式。[矛盾]证书   通常包含服务器名称,可信证书颁发机构   (CA)和服务器的公共加密密钥。
  •   
  • 客户可以联系   颁发证书的服务器(如上所述的可信CA)和   在继续之前确认证书的有效性。
  •   
  • 为了   生成用于安全连接的会话密钥,即客户端   用服务器的公钥加密随机数并发送   结果到服务器。只有服务器应该能够解密它,   用它的私钥。
  •   
  • 从随机数中,双方生成   加密和解密的关键材料。[矛盾]这个   结束握手并开始安全连接,即   使用密钥材料加密和解密,直到连接   关闭。
  •   
     

如果上述任何一个步骤失败,则TLS握手失败,并且   没有创建连接。

来源:Wikipedia

那么,有可能吗?是。我被告知一切皆有可能。它可能很昂贵,但它总是可能的。

我想完全透露我不是一名安全专业人士,只是一名爱好者。我不建议尝试将其用于生产级项目或除您​​自己的启发之外的任何其他项目。您应该明确地查看this SO post,其中提供了有关设置您自己的安全协议的障碍的绝佳解释。

但是,如果你想继续前进,可以想到一些想法。无论你直接参与这个项目,这些都是现实。

  • 所有主流现代浏览器都支持HTTPS。即使有了这个现实,HTTPS加载时间也比普通HTTP慢。如果没有广泛的生产,很可能您的替代实施将是安全的一小部分,同时明显更慢。这将是任何本土实现的缺点,除非您使用浏览器功能,这使我们完全回到使用TLS,这是现代HTTPS使用的。

  • 如果您设法在浏览器端使用Javascript以不可预测的方式在没有TLS的情况下加密密码,以至于MiTM攻击很困难,请不要在那里休息。您还应该保护您来回发送的数据。否则加密的密码确实无关紧要。当然,攻击者可能不知道bobsmith109的密码,但他并不需要它,因为他可以嗅探网络上的每一个活动。他知道bobsmith109登录的次数,可能跟踪他的IP以及你来回发送的任何其他敏感数据。

  • 无论采取何种安全措施,都有深度安全保障。因此,您可以立即做的一件事是确保您在数据库中加密数据,同时还需要强密码。

我重申,我是一名安全专业人员而且强烈反对这是除了满足您的好奇心之外的任何事情。天文数据不太可能,你可以创建一个可行的TLS替代方案,而没有一大群安全专业人员为一个项目贡献数年甚至数十年,这是SSL / TLS可以夸耀的。话虽如此,如果你选择继续前进,一个很好的起点是看看上面的握手模型,看看如何在没有TLS的情况下实现这个版本。

我不愿意在我的帖子中分享使用HTTPS的大多数现实障碍正在积极反对。最大的成本之一 - 非常接近成为一个非问题。免费证书颁发机构将于2015年第二季度推出,其中包括一些大型枪支,包括Mozilla和Akamai,仅举几例。 Here is an article

答案 8 :(得分:1)

不使用HTTPS登录,如何保护?

由于您的服务器和客户端之间没有安全通道:

  • 因为没有安全通道,任何人都可以窥探您的流量。
  • 因为任何人都可以窥探流量,你可以接受MITM攻击。
  • 因为您对MITM攻击持开放态度,所以无法保证客户端会看到合法页面。
  • 因为页面不合法而且你的页面实际上没有被提供(中间的人正在为页面提供服务),所以服务器端使用的所有技巧都变得无用。

你能做什么? Theorically?

  • 客户端和服务器都需要使用加密来使snooping / MITM不易受到影响。
  • 假设你无法握手,
  • 假设您的客户已经拥有您的密钥,并且知道如何与服务器说同样的胡言乱语。
  • 如何通过HTTP进行一些SSL,但是在base64编码的消息中包含一些乱码?

但是等等......既然你说过没有神奇的二进制文件或插件,甚至连RSA,我都不知道除了(某些可能非常弱的)内部加密之外是否还有其他任何可能。

-

答案 9 :(得分:1)

您可以尝试通过使用公钥加密(可能是GPG)并使用浏览器缓存来复制它。

  

这不是安全的东西,即使只是提出SSL对于复杂的攻击者来说也是不够的,你需要利用HSTS,公钥固定等来考虑网站的安全今天

其余的答案只是值得深思。

  1. 创建公钥 - 私钥对。保持私人安全。
  2. 创建包含公钥和encrypt函数的js文件,找到安全加密算法。此函数应使用附加时间戳加密给定字符串(序列化表单),以避免复制攻击。
  3. 使用Cache-Control:public, max-age=31536000 HTTP标头提供此文件。我们尝试缓解攻击者何时尝试替换脚本。该文件将始终从浏览器缓存中提供。
  4. 使用encrypt功能通过Javascript发送所有表单。使用与上面相同的标题提供这些服务。
  5. 在服务器端,decrypt数据,检查时间戳,如果它仍然有效。如果不是,那么丢弃它。
  6. 创建一个cookie令牌,只能在很短的时间内使用一次。如果攻击者捕获了cookie,他将没有太多时间做任何事情。但是,如果攻击者足够快,那么他可能会将原始用户注销。
  7. 每次回复都更改Cookie。但是,当用户一次发送多个请求然后以相反的顺序到达时,您会怎么做?哪个cookie有效?这会以虚假的安全感为代价造成大量问题。
  8. 任何侦听器都无法使用来回传输的数据,并且他们将无法更改/注入现有的 JS文件,直到缓存expires / user清除缓存。但是,任何复杂的攻击者都可以替换整个HTML文件,这会丢弃我刚才提到的所有安全措施。如果您至少可以在HTTPS上提供此文件/表单,那么可能会躲开它,将它们放在github页面或其他任何内容上。但是,如果您将文件放在其他域中,则需要为接收域设置CORS才能使其生效。

    另一次尝试

    一次性密码发送到电子邮件。

    1. 用户填写他们的电子邮件,点击一个链接,然后发送一个链接到他们的电子邮件,其中包含一个令他们登录的令牌。
    2. 用户点击链接
    3. 服务器检查令牌,将用户登录。
    4. 像上一个例子一样滚动cookie。
    5. 总而言之,无论你做什么,它都不安全。鉴于一个快速,复杂的攻击者,没有任何阻碍。

      获取SSL,如果基础架构不支持,请更改它。如果您的经理不相信SSL,请说服他/她。不要造成虚假的安全感。保护用户的数据,根据您所在的位置,法律要求您保护用户的数据。

      然后我们来谈谈如何使用SSL保护网站安全。

答案 10 :(得分:0)

使用非对称密码创建公钥/私钥对。

在服务器上创建一个对称密钥。

将公钥发送到客户端。

为对称密码客户端创建一个随机密钥。

使用公共密钥客户端对随机密钥进行加密。

将加密密钥发送到服务器。


服务器执行以下操作:

a。使用私钥解密随机对称密钥。

b。创建一个包含生成的客户端密钥的令牌。

c。对令牌进行签名。

d。使用服务器对称密钥对令牌进行加密。

e。用客户端生成的密钥对已经加密的令牌进行加密。

f。向下发送加密的令牌。


客户端收到此令牌并执行以下操作:

a。用生成的密钥解密令牌。

b。存储解密的令牌。

c。此时,仅使用服务器对称密钥对存储的令牌进行加密。


在从客户端到服务器的所有位置:

a。使用客户端生成的密钥对出站数据进行加密。

b。发送令牌+加密数据


服务器收到的每个请求

a。使用服务器对称密钥解密令牌。

b。验证签名。

c。使用存储在令牌中的客户端生成的密钥解密数据。

答案 11 :(得分:0)

查看 "The Secure Remote Password Protocol"

不要自己制定,而是让我引用他们的网站:

  

安全远程密码协议对短人类可记忆密码执行安全远程身份验证,并抵御被动和主动网络攻击。

  

[该]协议将零知识证明技术与非对称密钥交换协议相结合,与相对强大的扩展方法相比,可以显着提高性能,这些方法可以抵御诸如增强EKE或B-SPEKE之类的被盗验证者攻击。

虽然斯坦福大学本身并不提供PHP和JavaScript的实现,但它们链接到一些第三方实现。

其中一个链接指向" Clipperz" ,这是一个在线密码管理器。它也可以作为GitHub上的社区版本提供。他们在那里托管了"javascript-crypto-library",它实现了协议和"password-manager"本身,它包含用PHP和Python编写的后端。

我无法说出提取代码的相关部分有多困难,但也许您可以重复使用它们的实现(它在AGPL下获得许可)。

修改2014/10/24:

Wikipedia's article on SRP列出了更多实现。与PHP / JS相关:

答案 12 :(得分:-1)

我见过的有点安全HTTP连接的最佳解决方案是使用md5sum(或其他一些哈希)的Javascript实现来避免以明文传输密码。您可以在Javascript中创建一个表单onsubmit处理程序,用一个原始值的哈希值替换密码字段。这为不安全的连接增加了适度的安全性,但依赖于在浏览器中运行的Javascript才能正常工作。

答案 13 :(得分:-2)

我在我的系统上遇到同样的问题。我已采取措施尝试提高安全性,同时不会影响使用复杂机制的用户体验。我注意到绝大多数用户使用相同的浏览器(但不一定是相同的IP地址)从同一台机器登录,或者从几个浏览器(例如:桌面或移动设备)登录。我决定用它来识别一种模式。

1)在注册过程中,用户需要具有强密码(以防止字典攻击),安全问题/答案和标准电子邮件验证(作为真人的证明)

2)在登录期间,在5次登录尝试失败后(之前),将显示验证码以防止暴力攻击。

3)最后,我在成功登录后创建了一部分用户代理字符串的哈希值,其中包含用户操作系统,浏览器(一般不是版本)和语言 - 形成一种二级密码。如果下次登录时useragent哈希显着不同,则要求用户回答安全问题。然后,如果回答令人满意,则将新的UA字符串进行散列并添加到其“安全机器”列表中,以便不再从该机器中询问它们。这类似于Steam游戏系统采用的机制。

这已经成功使用了一年多,大约有700名用户,并且还有一个额外的好处,就是防止“登录共享” - 多个用户使用相同的凭据以方便使用的问题!

答案 14 :(得分:-2)

我猜你关心密码到服务器的安全传输?我的回答是:不要将密码传输到服务器:)

事实上,您可能无法从浏览器(用户)向服务器传输任何内容以对用户进行身份验证,因为正在侦查http流量的攻击者也可以重新传输数据并进行身份验证。

<强>提案:

明显的解决方案是使用源自服务器的单向一次性事务认证;就像一个只能使用一次的交易号。最后,您仍需要一个安全通道,以便与用户同步交易号码列表。

你可以使用google authenticator,但是你需要一个安全通道来设置任何一方的参数。如果您认为电子邮件是安全的,那将是一种方法。

答案 15 :(得分:-2)

答案更短,如果你对安全真的很重要,你总是可以选择不同级别的政府。

Absolut安全性不存在。头号缺陷始终在客户端,特洛伊木马 ans 键盘记录器。 SSL没有帮助。

1)令牌生成器:银行使用它们,然后暴雪使用它们。它可以是设备或应用程序。嗯..这很贵。

2)短信指针。有趣而实惠的解决方案市场上的trnasactional短信价格很高,每个人都有一部能够接收它的手机。

3)如果您必须使用HTTP,则可以强制使用第三方oauth服务,例如 google facebook 。如果没有令牌生成器,这是最好的。

答案 16 :(得分:-3)

如果您无法使用HTTPS,或者您不想使用HTTPS,请考虑使用jCryption。 jCryption为通过HTTP请求(POST,GET等)发送的数据提供加密。

您可以在此处测试此技术:http://www.jcryption.org/#examples

如果你正在使用Firebug,你会发现所有数据都已加密。

它有用于加密前端数据的jQuery库和用于解密后端数据的PHP库。

答案 17 :(得分:-3)

使用散列机制来存储密码并始终比较散列密码,然后即使您没有人知道真实密码。 这很简单,但它很有效。但是,没有什么是完全安全的,并且有一些方法可以打破精简层。

答案 18 :(得分:-4)

很难以确保没有trusted third party的通信,但是,有一些安全技巧可供您使用:

请勿将用户的敏感信息暴露给公共网络。

每个敏感信息都应加密或加密公钥。 注意:如果您选择使用公钥加密用户的敏感信息,请确保用户可以验证公钥。例如,您可以通过短信甚至自动呼叫向用户发送某种公钥密钥指纹。

成功登录后生成共享秘密

在安全登录事务之后,应生成共享密钥。生成过程可以参考SSL Handshake注意:生成共享密钥后,必须再进行传输。它的唯一功能是在ServerBroswer

之间加密/解密数据

应该进行两步验证以避免重复攻击

这些技巧可以帮助你

答案 19 :(得分:-4)

试试这个:在登录页面的每个请求上,发送一个nonce和一个时间戳。 发布到服务器时,发送以下四个详细信息:

明文中的用户名,随机数和时间戳。 然后将上面的内容与分隔符(例如:换行符)连接起来,并使用用户密码作为链式分组密码模式的加密进行加密。

在服务器端使用用户名查找密码并验证加密字符串。

由于密码永远不会以明文形式发送,因此它是安全的,可以使用时间戳来避免重新提交相同的数据。

为了避免通过中间人攻击获取会话密钥来劫持会话,密码或密码的哈希值可以由客户端上的应用程序存储在内存中并用于生成用于服务器验证的唯一会话密钥。

看一下OAuth 1.0也不错。