【问题标题】:Use JavaScript encryption module instead of SSL/HTTPS使用 JavaScript 加密模块而不是 SSL/HTTPS
【发布时间】:2011-07-05 22:24:18
【问题描述】:

使用一些 JS 加密库而不是 SSL 来进行安全通信是否值得?我问这个是因为我想保护我在 Google App Engine 上构建的应用程序,它不允许您使用自己的域进行 SSL 请求。与 GAE 进行安全通信的好方法是什么?谢谢。

【问题讨论】:

  • 我不得不说不。JS 加密!= SSL。远非如此。
  • SSL 为您提供了很多好处,例如声誉不佳(客户可以相信您就是您所说的自己),以及保护中间人攻击。当 SSL 为您提供更多功能时,JS cypto 库并不是一个好主意。
  • @russau:虽然正是因为“不能使用自己的域进行 HTTPS”的事情,GAE 并没有让客户相信你就是你所说的那个人。它让客户相信你是谷歌(即他们正在与谷歌交谈),因为它是谷歌在证书上的名字。他们也可能认为 Google 是在代表您所说的自己行事,但如果是这样,那并不是因为 SSL 已经证明了这一点。

标签: javascript google-app-engine ssl


【解决方案1】:

[注意:请参阅下面的更正]

可以通过自定义域与谷歌应用引擎上经过身份验证的服务器进行安全通信,但这很麻烦。正如其他一些答案所表明的那样,您必须非常小心如何实施加密以防止中间人攻击。

这里是python的基本说明,但你可以修改为java。预计至少要花一两天时间来启动和运行这样的东西。

先决条件:

  • 用于服务器的 python RSA 和 AES 库。 pyCrypto 在 GAE 上运行良好。
  • 要在客户端上运行的 javascript RSA 和 AES 库。我将stanford's RSA librarycrypto-js 用于AES。我不记得为什么我不只使用一个库。

说明:

  • 第 1 步:离线,创建 RSA 公钥和私钥对。这是pyCrypto 的说明。

  • 第 2 步:将生成的 RSA 公钥和私钥保存在 python 文件中,确保私钥不可公开访问。

  • 第 3 步:在服务器上,创建一个生成 javascript 文件的请求。 javascript 文件应该只将公钥传输给客户端。例如,它只会返回一个包含以下内容的文件:

    var public_key="[your public rsa key here]"

  • 第 4 步:在您的 app.yaml 文件中,确保生成的 javascript 文件仅通过 SSL 提供(即设置 secure: always)。见instructions here

  • 第 5 步:在客户端上,使用 ssl 加载 javascript 文件。但是,不要使用您的自定义域,而是使用 appspot 域。例如,将此添加到您的 html 文件中:

<script src="https://example.appspot.com/publicKey.js"></script>

客户端现在将拥有一个经过身份验证的 RSA 公钥,以防止中间人攻击。 注意:浏览器通常禁止访问其他域以防止XSS,但有一个漏洞可以让您加载javascript文件。

  • 第 6 步:在客户端上,生成一个随机私钥。使用javascript RSA library 和我们在步骤 4 中获得的公钥来加密随机私钥。将加密后的私钥发送到服务器。

  • 第 7 步:在服务器端,使用 RSA 私钥解密客户端生成的随机密钥。

    此时,服务器和客户端都拥有相同的私钥。更好的是,由于原始公钥是通过 SSL 传输的,我们可以验证服务器是否真的是我们所相信的(即没有中间人)。

  • 第 8 步:现在服务器和客户端可以使用随机生成的私钥及其各自的 AES 库来加密和解密他们想要的任何数据。

-- 编辑:更正--

Bruno 下面的评论是 100% 正确的,上述步骤是不安全的。尽管上述步骤确实可以在客户端和服务器之间建立经过身份验证的会话,但用户真正知道它已通过身份验证的唯一方法是他们检查代码以确保使用 https 加载公钥。中间人可以为初始 html 页面提供服务,修改 <script src="https://... 代码以指向其他内容。

请查看wwwizer.com

【讨论】:

  • 使用 JavaScript 加密毫无意义,因为客户端永远无法确定它真正来自服务器(除非您也使用 HTTPS,但这会使 JS 加密变得多余) )。
  • 上述步骤确实进行了身份验证,因为它们使用 SSL 进行公钥分发。所以他们可以确定公钥实际上来自正确的服务器。是的,这里有一点冗余。您可能会让服务器生成私钥并通过 SSL 在 javascript 文件中传输它,因此不需要处理 RSA。但是,这会引发其他问题。如果不重新加载页面,您将无法更改私钥。
  • 您不能认真地期望用户检查页面的源代码或使用开发人员工具来验证它是否正确使用了src="https://..." URI:作为用户,您真的不知道什么你得到,或者你从哪里得到它(能够在浏览器中看到蓝/绿条是有道理的)。另外,JavaScript crypto has other shortcomings。不要试图通过 JavaScript 模拟 SSL/TLS over HTTP:使用浏览器直接支持的 SSL/TLS。
  • 我想了想,你是 100% 正确的。如果有人修改了包含 script 标签的原始 html 文件,上述步骤是不安全的。谢谢。
  • 虽然这浪费了大量时间,但对于如何错误地进行安全通信来说,这是一次极具教育意义的经历。感谢您指出。
【解决方案2】:

Javascript 是一种客户端语言,这意味着它在用户的浏览器中运行,因此任何用户都可以随意更改、操作和禁用它;使您的加密无用。

编辑:你不是说 Java 吗?

【讨论】:

  • 所以,实际上,更重要的问题是如何在我自己的域上(而不是在 appspot.com 上)使客户端和我的 GAE 应用程序之间的连接安全,并且使用 JS 库是一种想法。所以,我想我应该更好地了解如何处理应用程序限制而不是使用 JS 加密库。谢谢。
  • 任何用户也可以更改、操纵和禁用他们的 SSL 连接端。 Javascript在这里没用,但不是因为用户可以修改它。
  • 好点尼克,启用安全性是用户的选择,这是为了他们自己的利益。而 JS 是不好的选择,因为它可能会因为其他原因而被禁用,具有讽刺意味的是,它通常是出于安全原因而被禁用的。
【解决方案3】:

不,这不值得,因为您必须以某种方式将 Javascript 代码发送给客户端。攻击者可以简单地修改 Javascript 以使他能够读取(或修改)所有通信,从而使您的所有保护措施无效。 SSL 确实是唯一的选择。

【讨论】:

    【解决方案4】:

    您必须使用 https,但您不能通过 appengine 在您自己的域上使用它。不过,他们说他们很快就会增加这种能力。我们一直在使用烦人的 https apppot 域,假设他们真的会添加对 https 自定义域的支持,但与此同时,我们 (~75) 的客户都没有抱怨过 apppot 的事情。

    我想真正的问题是有多少人因为 apppot 而不是客户......但我怀疑这是一个很小的数字。

    【讨论】:

    • 那么如何更好地构建我的应用程序来处理appspot.com 上的https?我应该如何组织它?谢谢。
    • @Sergey 你根本不需要改变你网站的架构。您可以将某些路径限制为“仅安全”,以便无法通过 http 访问它们。另外,请注意,您在 yourdomain.com 上设置的任何 cookie 都不会在 yourdomain.appspot.com 上可见。
    • 我正在构建我的应用程序,大量使用 AJAX/JSON,其中界面中的几乎所有元素都是使用 AJAX 请求构建的。我该如何处理?谢谢。
    • 如果主机页面通过 https 发送,AJAX 请求将自动通过 https。您无需担心。
    猜你喜欢
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    相关资源
    最近更新 更多