2

我正在开发一个利用面向服务架构的新站点,前端使用纯 JavaScript,通过 RESTful AJAX 调用访问 Web 服务以获取数据。

它不应该特别重要,但我的堆栈是:

  • javascriptMVC
  • jQuery
  • 引导程序
  • ASP.NET Web API(.NET 4.0 上的 C#)
  • 微软 SQL

这篇文章中,我找到了一些在客户端 (JavaScript) 和服务器(通过 Web API 的 REST 服务)之间共享私钥后保护 Web 服务调用的好方法。但是,我正在为如何建立用于加密的私钥而苦苦挣扎。

坏主意#1

最初的设置是在登录时通过 HTTPS 进行设置,然后将其存储在客户端的 cookie 中以供重复使用。问题是我们的 SSL 证书适用于https://secure.example.com,而我们的网站位于http://www.example.com - 所以我无法访问 secure.example.com cookie来自 www.example.com。

坏主意#2

我的下一个想法是通过 URL 参数将其加密并签名,从 HTTPS 登录到 HTTP 登录后页面,如下所示:

http://www.example.com/processLogin?key=[encryptedKey]&sig=[encryptedSig]&user=[userid]

encryptedKey 和 encryptedSig 都将使用另一个仅针对该交易存在的私钥进行加密。它将在登录时创建并分配给数据库中的该用户。在 HTTP 端,所有这些都被传递到解密它的服务器,验证签名,删除该私钥(以防止重放攻击 - 本质上是一个随机数)并返回解密的私钥([encryptedKey]解密)。

从那时起,解密后的值[encryptedKey]将用于所有未来的交易。问题是解密的私钥必须通过 HTTP 通过线路发送,这很糟糕。

坏主意#3

我还短暂地想到在 JavaScript 中有一个硬编码的密钥,用于解密这个值,但无论我如何尝试和混淆它,黑客都可以找到并使用它。

坏主意#4

我还考虑过在初始握手时使用公钥加密进行某种密钥交换,但如其他地方所述,除非结束,否则您不能在客户端真正确信在初始握手期间没有篡改SSL - 让我回到第一方。

大问题

那么,你们如何在不通过 HTTPS 的情况下管理这些事情呢?我的 HTTP 和 HTTPS 是否必须具有相同的域名,以便我可以将此私钥存储在 cookie 中?

请注意,该站点的非 SSL 部分不会共享信用卡或登录信息等。我只是不想让这个傻瓜敞开。

4

3 回答 3

2

如果不实施 SSL,您将无法在 javascript 客户端和服务器之间进行安全和加密的通信。是不可能的。如果您真正想要完成的不是加密流量,而只是确保您正在与之交谈的客户端已被授权发出请求并且客户端不是模仿者,那么 OAuth 可能就足够了。请参阅http://www.dotnetopenauth.net/了解标准 OAuth .net 实施。

如果 OAuth 不是您想要参与的,而您只是想在已经构建的基础上进行构建,您应该向 javascript 客户端分发令牌以及公钥和私钥。公钥和令牌是每次请求来回发送的内容,而私钥永远不会来回发送,而是用于生成某种类型的签名哈希。每个请求都应该有这个签名和一个基于时间的随机数来防止重放。您还应该非常频繁地使令牌过期,并要求客户端使用他们的签名和公钥请求“刷新”令牌。本质上,我所描述的是 OAuth 1.0a,如果您确实想走这条路,我会参考 DotNet OpenAuth 而不是自己尝试推出它。

但是,重申一下,如果没有 SSL,您仍然容易受到其他类型的攻击。此外,除非您对初始令牌请求进行 SSL 加密,否则黑客总是可以嗅探令牌/公钥/私钥对的初始交付,因此,首先消除您为确保事情安全而付出的所有努力。

上述方法的替代方法是在您的客户端和 REST API 之间放置一个代理服务器。对 API 的请求只能通过代理服务器。客户端登录并 使用基本身份验证从https://secure.example.com获取 cookie。然后,客户端继续向 secure.example.com 发出请求,然后 secure.example.com 向您的 API 发出请求并将数据返回给客户端。

无论如何,希望有足够的信息让你深思。

于 2012-08-22T18:56:16.920 回答
1

您可以通过查看以下答案来查看如何使用子域和 cookie:在域上创建 javascript cookie 并跨子域读取它

于 2012-08-22T17:58:03.900 回答
0

关于坏主意#3:

我早就知道我可以使用http://jsbeautifier.org对使用http://dean.edwards.name/packer/与“收缩变量”复选框和/或“Base62 编码”进行混淆的任何内容进行反混淆“复选框。因此 JavaScript 是完全不安全的,不应依赖于保存任何类型的 SSL 加密、用户身份验证令牌或浏览器中的可编辑帐户统计信息。否则有人会简单地尝试编辑他们的游戏帐户并给自己+1000万游戏币。

当一切都通过 SSL 时,它只能防止“中间人”攻击。这实际上是一种“中间服务器”攻击。它不会阻止最终用户自己成为黑客。

在下一个示例中,SSL 将阻止服务器 a 到 e 看到任何从客户端传递到终端服务器的数据,但如果没有 SSL,服务器 C 将窃取数据。这就是服务器跃点的工作方式,无需加密,客户端 + 所有服务器都可以读取数据:

client > a > b > server c's bot sniffs http traffic > d > e > terminus server

服务器 c 的机器人记录了一个信用卡号,这是一个加密的银行帐号。(大多数人没有意识到信用卡号是经过加密和转换的银行帐号。如果信用卡号被泄露,银行很容易从银行帐号重新签发新的加密 CC# 并发送邮寄一张新卡。他们不必更改原始银行帐号,也不必打印底部印有银行帐号的新支票。)

使用 TLS/SSL/https 加密的服务器跃点将像这样工作,只有客户端和服务器可以读取任何内容:

client > all servers from a-e are blind & pass the data through > terminus server

如果服务器 c 的机器人可以使用 SSL 读取任何内容,则服务器 c 的机器人会看到类似:as65a89as7df08 而不是 1234-5678-9012-... 的垃圾。

iOS 最酷的地方在于,当它与 HTML 5 和 CSS 一起使用时,它使得阅读 JS 代码变得更加困难。用户不能像在桌面浏览器中那样右键单击以在他们的 iPhone 上进行检查。使用后端语言在终端服务器中隐藏密码很容易。

目前无法防止 JavaScript 被最终用户(客户端)入侵。每个最终用户都可能是黑客。如果我想出别的东西,我可以把它贴在这里供未来的开发人员阅读。

于 2016-03-17T23:17:19.800 回答