【问题标题】:Two-way password encryption without ssl无需 ssl 的双向密码加密
【发布时间】:2010-09-07 12:28:02
【问题描述】:

我正在使用 basic-auth twitter API (no longer available) 将 twitter 与我博客的评论系统集成。这个和许多其他 Web API 的问题是它们需要用户的用户名和密码才能做任何有用的事情。我不想处理安装 SSL 证书的麻烦和成本,但我也不希望密码以明文形式通过网络传递。

我想我的一般问题是:如何通过不安全的渠道发送敏感数据?

这是我目前的解决方案,我想知道其中是否有任何漏洞:

  1. 在服务器上生成一个随机密钥(我用的是php)。
  2. 将密钥保存在会话中,并将密钥输出到 javascript 变量中。
  3. 在提交表单时,使用Triple DES in javascript 和密钥来加密密码。
  4. 在服务器上,使用会话中的密钥解密密码,然后销毁会话。

最终结果是只有加密的密码通过网络发送,并且密钥只使用一次,并且永远不会与密码一起发送。问题解决了吗?

【问题讨论】:

  • 你做不到。 SSL 很昂贵,因为所有浏览器都信任的第三方已经验证您的服务器是给定域名的真实服务器。当攻击者可以强迫用户认为他们的服务器是您的域的主机并且这种攻击需要瞬间在 wifi 或以太网网络(图书馆、学校、办公室等)上执行时,加密是无用的。请参阅 security now 播客的背面目录以了解所有问题,您很快就会决定从便宜的人那里购买 SSL 证书更容易、更便宜。

标签: javascript security encryption passwords


【解决方案1】:
  1. 在服务器上生成一个随机密钥(我用的是php)。
  2. 将密钥保存在会话中,并将密钥输出到 javascript 变量中。
  3. 在提交表单时,使用 JavaScript 中的 Triple DES 和密钥来加密密码。

这避免了通过网络以明文形式发送密码,但它要求您通过网络以明文形式发送密钥,这样任何人都可以窃听来解码密码。

前面已经说过了,我再说一遍:不要试图编造自己的加密协议!已经为这种事情制定了既定的协议,这些协议已经被专业人士创建、同行评审、击败、黑客攻击、戳戳和刺激,使用它们!没有人能够做到想出比整个加密和安全社区一起工作更好的东西。

【讨论】:

  • +1 表示“不要尝试编写自己的加密协议!” :D
【解决方案2】:

你的方法有一个缺陷——如果有人拦截了向用户传输的密钥和用户的加密回复,他们可以解密回复并获取用户的用户名/密码。

但是,有一种方法可以通过不安全的介质安全地发送信息,只要信息在传输过程中不能被修改,称为Diffie-Hellman algorithm。基本上,两方能够根据他们的对话计算用于加密数据的共享密钥 - 但观察者没有足够的信息来推断密钥。

虽然设置客户端和服务器之间的对话可能很棘手,而且比简单地将 SSL 应用到您的网站要耗费更多时间。您甚至不必为此付费 - 您可以生成提供必要加密的自签名证书。这不能防止中间人攻击,但 Diffie-Hellman 算法也不能。

【讨论】:

  • “只要信息不能在传输过程中被修改”——这在没有 SSL 的情况下通过 http 连接几乎是不可能实现的。修改传输中的信息很简单。
【解决方案3】:

您不必在服务器上拥有证书;是否愿意与未经身份验证的服务器交谈取决于客户端。仍然可以执行密钥协商以建立私有通道。但是,将私有凭据发送到未经身份验证的服务器并不安全,这就是为什么您在实践中看不到这种方式使用 SSL。

回答您的一般性问题:您只需发送它。我认为您的真实一般性问题是:“我如何通过不安全的渠道发送敏感数据——并保证它的安全?” 你不能。

听起来您已经决定安全性不值得每月 10 到 20 美元的证书费用,并且为了保护 Twitter 密码,这可能是真的。那么,为什么要花时间提供安全的假象呢?只需向您的用户说明,他们的密码将以明文形式发送,并让他们自行选择。

【讨论】:

    【解决方案4】:

    那么这如何更安全?即使您可能已经保护了浏览器您的服务器,那么 Internet 的其余部分(您的服务器twitter)呢?

    恕我直言,要求其他服务的用户名和密码并期望人们输入是不可接受的。如果您非常在意 - 在他们正确处理并重新启用 OAuth 之前不要整合它们。 (他们支持了一段时间,但几个月前就禁用了。)

    同时,为什么不提供 OpenID?每个 Google、Yahoo!、VOX 等帐户都有一个。人们可能没有意识到这一点,但他们已经拥有 OpenID 的可能性非常非常高。 Check this list 看看我的意思。

    【讨论】:

    • 请你解释一下你第二段的第一句话?只要您信任询问您的用户名和密码的网站,为什么会不可接受?它可以减少密码疲劳,如果安全实施(HTTP Secure、SSL/TLS,...),它会非常有用。此外,这通常是 StackOverflow 所做的,例如允许我们使用 Google 帐户。最后,仍有大量电子邮件提供商不支持 OpenID 和 OpenID Connect。
    【解决方案5】:

    当密钥在客户端和服务器之间发送时,它是明文并且会被拦截。将其与密码的加密文本结合起来,密码就被解密了。

    Diffie-Hellman 是一个很好的解决方案。如果您只需要对它们进行身份验证,而不是实际传输密码(因为密码已经存储在服务器上),那么您可以使用HTTP Digest Authentication,或者其他一些变体。

    【讨论】:

      【解决方案6】:

      API 和 OAuth

      首先,正如其他人所说,您不应该使用用户密码来访问 API,您应该得到一个OAuth token。这将允许您代表该用户执行操作,而无需他们的密码。这是许多 API 使用的常用方法。

      密钥交换

      如果您需要解决通过不安全连接交换信息的更普遍问题,其他答案中提到了几种密钥交换协议。

      一般而言,密钥交换算法对窃听者来说是安全的,但由于它们不验证用户的身份,因此容易受到中间人攻击。

      来自Diffie Hellman 上的维基百科页面:

      在原始描述中, Diffie-Hellman 交换本身不提供身份验证 通信方,因此很容易受到 中间人攻击。中间的一个人可以建立两个 不同的 Diffie-Hellman 密钥交换,一个与 Alice,另一个 与 Bob 一起,有效地将 Alice 伪装成 Bob,反之亦然, 允许攻击者解密(并读取或存储)然后重新加密 他们之间传递的信息。一种身份验证方法 通常需要相互通信的各方来防止 这种类型的攻击。 Diffie-Hellman 的变体,例如STS,可能是 而是用来避免这些类型的攻击。

      在某些情况下,即使 STS 也不安全,因为攻击者能够插入自己的身份(签名密钥)来代替发送者或接收者。

      身份和身份验证

      这正是 SSL 旨在解决的问题,通过建立“受信任”签名机构的层次结构,理论上验证谁拥有域名等,连接到网站的人可以验证他们确实在与该域的服务器进行通信,而不是与将自己置于其间的中间人进行通信。

      您可以创建一个自签名证书,该证书将提供必要的配置来加密连接,但不会保护您免受中间人攻击,原因与未经身份验证的 Diffie-Hellman 密钥交换不会。

      您可以从https://www.startssl.com/ 获得有效期为 1 年的免费 SSL 证书 - 我将它们用于我的个人网站。不管这意味着什么,他们并不那么“受信任”,因为他们只对申请的人进行自动检查,但它是免费的。还有一些服务费用很低(英国 123-Reg 每年 10 英镑)。

      【讨论】:

        【解决方案7】:

        我采用了不同的方法

        1. 服务器:存储在数据库中的用户名和密码哈希
        2. 服务器:使用表单发送质询以请求密码,将其与时间戳和客户端 IP 地址一起存储在会话中
        3. 客户端:散列密码,连接挑战|用户名|密码散列,再次散列并发布到服务器
        4. 服务器:验证时间戳、IP,进行相同的连接/散列并进行比较

        这适用于密码传输。将它用于数据意味着使用最终的哈希作为明文的加密密钥,并生成一个随机初始化向量与密文一起传输到服务器。

        有这方面的cmet吗?

        【讨论】:

          【解决方案8】:

          客户端 javascript 安全性的问题在于,攻击者可以将传输中的 javascript 修改为简单的 {return input;} 从而使您精心设计的安全性变得毫无意义。解决方案:使用浏览器提供的(即不传输)RSA。据我所知,目前还没有。

          【讨论】:

            【解决方案9】:

            如何通过 不安全的渠道

            使用预先共享的密钥。这是您在建议的解决方案中尝试的方法,但您不能通过不安全的通道发送该密钥。有人提到DH,它会帮助你协商一个密钥。但 SSL 所做的另一部分是提供身份验证,以防止中间人攻击,以便客户端知道他们正在与他们打算与之通信的人协商密钥。

            对于 99.99% 的工程师来说,Chris Upchurch 的建议确实是唯一好的答案 - 不要这样做。让其他人去做并使用他们的解决方案(比如编写 SSL 客户端/服务器的人)。

            我认为理想的解决方案是让 Twitter 支持 OpenID,然后使用它。

            【讨论】:

              【解决方案10】:

              自签名的 ssl 证书不花钱。对于免费的 twitter 服务来说,这对用户来说可能还不错。

              【讨论】:

                【解决方案11】:

                到奥利

                例如,在您的方法中,我与同一路由器位于同一子网中,因此我在工作中获得与同事相同的 ip。我在浏览器中打开相同的 url,因此服务器生成具有相同 ip 的时间戳,然后我使用 tcp/ip 转储从我的同事连接中嗅探散列或非散列密码。我可以嗅出他发送的所有内容。所以我有他表格中的所有哈希值,你也有时间戳(我的)和相同的 ip。所以我使用发布工具发送所有内容,嘿,我正在登录。

                【讨论】:

                  【解决方案12】:

                  如果您不想使用 SSL,何不尝试一些其他协议,例如 kerberos?

                  这里有一个基本的概述: http://www.kerberos.org/software/tutorial.html

                  或者,如果您想更深入一些,请参阅 http://www.hitmill.com/computers/kerberos.html

                  【讨论】:

                  • IMO,这比安装 SSL 证书更麻烦。
                  【解决方案13】:

                  我有一个类似的问题(想在不支付 ssl 证书的情况下加密表单中的数据)所以我做了一些搜索并找到了这个项目:http://www.jcryption.org/

                  我还没有使用它,但它看起来很容易实现,我想我会在这里分享它,以防其他人正在寻找类似的东西并像我一样发现自己在这个页面上。

                  【讨论】:

                  • 既然我已经使用了这个项目,我可以说如果你使用 PHP,它非常棒并且很容易集成到项目中。当然,它并不能真正为您提供 100% 的保护,see here 但如果您只是在寻找一种方法来添加更多保护,而不是在清晰测试的帖子中发送表单元素......这是一个不错的选择。跨度>
                  猜你喜欢
                  • 2011-07-02
                  • 2010-09-16
                  • 2011-09-14
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-01-16
                  相关资源
                  最近更新 更多