首页 文章

如何通过HTTP安全地发送密码?

提问于
浏览
101

如果在登录屏幕上用户使用其用户名和密码提交表单,则密码将以纯文本形式发送(即使使用POST,如果我错了也请更正) .

那么问题是,保护用户及其密码的正确方法是针对可能窃听通信数据的第三方?

我知道HTTPS是问题的解决方案,但有没有办法确保使用标准HTTP协议(POST请求)至少某种程度的安全性? (也许以某种方式使用javascript)

EDIT 我可能遗漏了一些重要的事情 .

我的目的是一个页面 - 这是PHP生成的登录页面,当然在HTTP GET请求中作为HTML文件发送给用户 . 服务器和客户端之间没有 Build (@Jeremy Powel)连接,所以我无法创建这样的握手协议 . 我希望整个过程对用户透明 - 他想提交密码,而不是处理加密 .

谢谢 .

8 回答

  • 13

    使用HTTP和SSL将使您的生活更轻松,您可以放心,非常聪明的人(至少比我聪明!)多年来仔细检查了这种保密通信方法 .

  • 55

    安全认证是一个广泛的主题 . 简而言之,正如@ jeremy-powell所提到的,总是倾向于通过HTTPS而不是HTTP发送凭据 . 它将带走许多与安全相关的头痛 .

    如今,TSL / SSL证书相当便宜 . 事实上,如果您根本不想花钱,那么就有一个免费的 letsencrypt.org - 自动证书颁发机构 .

    你可以更进一步,使用 caddyserver.com 在后台调用letsencrypt .

    现在,一旦我们将HTTPS取消了......

    您不应通过POST有效负载或GET参数发送登录名和密码 . 请改用Authorization标头(基本访问认证方案),其构造如下:

    用户名和密码组合成一个以冒号分隔的字符串,例如:username:password结果字符串使用Base64的RFC2045-MIME变体进行编码,但不限于76个字符/行 . 然后将授权方法和空格即“基本”放在编码的字符串之前 . 来源:维基百科:授权 Headers

    它可能看起来有点复杂,但事实并非如此 . 有很多好的库可以为您提供开箱即用的功能 .

    您应该使用Authorization标头有几个很好的理由

    • 这是一个标准

    • 这很简单(在您学习如何使用它们之后)

    • 它允许您在URL级别登录,如下所示: https://user:password@your.domain.com/login (Chrome会自动将其转换为 Authorization 标头)

    IMPORTANT:
    正如@zaph在下面的评论中指出的那样,将敏感信息作为GET查询发送并不是一个好主意,因为它最有可能最终出现在服务器日志中 .

    enter image description here

  • 4

    您可以使用质询响应方案 . 假设客户端和服务器都知道秘密S.然后服务器可以确定客户端知道密码(不给它):

    • 服务器向客户端发送一个随机数R.

    • 客户端将H(R,S)发送回服务器(其中H是加密散列函数,如SHA-256)

    • Server计算H(R,S)并将其与客户端的响应进行比较 . 如果它们匹配,则服务器知道客户端知道密码 .

    Edit:

    这里存在一个问题,即R的新鲜度和HTTP无状态这一事实 . 这可以通过让服务器创建一个秘密,称之为Q,只有服务器知道来处理 . 然后协议如下:
    服务器生成随机数R.然后发送给客户端H(R,Q)(客户端不能伪造) . 客户端发送R,H(R,Q),并计算H(R,S)并将其全部发送回服务器(其中H是加密散列函数,如SHA-256)服务器计算H(R,S)并将其与客户的回应进行比较 . 然后它需要R并计算(再次)H(R,Q) . 如果客户端的H(R,Q)和H(R,S)版本与服务器的重新计算匹配,则服务器认为客户端已经过身份验证 .
    需要注意的是,由于H(R,Q)不能由客户端伪造,因此H(R,Q)充当cookie(因此可以实际上作为cookie实现) .

    Another Edit:

    之前对协议的编辑是不正确的,因为任何观察过H(R,Q)的人似乎都能够用正确的哈希重放它 . 服务器必须记住哪些R不再新鲜 . 我正在CW这个答案,所以你们可以编辑这个并找出一些好的东西 .

  • 1

    如果您的webhost允许,或者您需要处理敏感数据,请使用HTTPS,period . (法律经常要求afaik) .

    否则,如果你想通过HTTP做一些事情 . 我会做这样的事情 .

    • 服务器将其公钥嵌入登录页面 .

    • 客户端填充登录表单并单击“提交” .

    • AJAX请求从服务器获取当前时间戳 .

    • 客户端脚本连接凭证,时间戳和盐(来自的哈希值)模拟数据,例如 . 鼠标移动,按键事件),使用公钥加密它 .

    • 提交结果哈希 .

    • 服务器解密哈希

    • 检查时间戳是否足够近(仅允许短5-10秒的窗口) . 如果时间戳太旧,则拒绝登录 .

    • 存储哈希值20秒 . 在此间隔期间拒绝用于登录的相同哈希 .

    • 验证用户 .

    因此,密码受到保护,无法重播相同的身份验证哈希 .

    关于会话令牌的安全性 . 那有点难了 . 但是有可能重新使用被盗的会话令牌 .

    • 服务器设置一个包含随机字符串的额外会话cookie .

    • 浏览器在下一个请求时发回该cookie .

    • 服务器检查cookie中的值,如果它不同则会破坏会话,否则一切都没问题 .

    • 服务器再次使用不同的文本设置cookie .

    因此,如果会话令牌被盗,并且其他人发送了请求,那么在原始用户的下一个请求中,会话将被销毁 . 因此,如果用户主动浏览网站,经常点击链接,那么小偷就不会对被盗令牌走得太远 . 可以通过对敏感操作(例如帐户删除)进行另一次认证来强化该方案 .

    关于实现:RSA可能是最常见的算法,但对于长密钥来说它很慢 . 我不知道PHP或Javascript实现的速度有多快 . 但可能有更快的算法 .

  • 23

    我会使用服务器端和客户端Diffie-Hellman密钥交换系统与AJAX或多个表单提交(我推荐前者),虽然我没有在互联网上看到任何良好的实现 . 请记住,MITM总是可以破坏或更改JS库 . 在某种程度上,本地存储可用于帮助解决这个问题 .

  • 9

    您可以使用SRP在不安全的通道上使用安全密码 . 优点是,即使攻击者嗅探流量或破坏服务器,他们也无法在不同的服务器上使用密码 . https://github.com/alax/jsrp是一个javascript库,它支持在浏览器或服务器端(通过节点)通过HTTP进行安全密码 .

  • 2

    HTTPS非常强大,因为它使用非对称加密技术 . 这种类型的加密不仅允许您创建加密隧道,还可以验证您是在与正确的人交谈,而不是黑客 .

    这是Java源代码,它使用非对称密码RSA(由PGP使用)进行通信:http://www.hushmail.com/services/downloads/

  • 0

    你可以使用ssl为你的主机有ssl的免费项目,如letsencrypt https://letsencrypt.org/

相关问题