我正在开发一个新网站,该网站采用面向服务的架构,前端使用纯 JavaScript,通过 RESTful AJAX 调用访问 Web 服务以获取数据。
它不应该特别重要,但我的堆栈是:
- javascriptMVC
- jQuery
- Bootstrap
- ASP.NET Web API(.NET 4.0 上的 C#)
- MS SQL
来自this article一旦我在客户端 (JavaScript) 和服务器(通过 Web API 的 REST 服务)之间共享私钥,我就找到了一些保护 Web 服务调用安全的好方法。但是,我正在努力解决如何建立用于加密的私钥。
坏主意#1
最初是在登录时通过 HTTPS 进行设置,然后将其存储在客户端的 cookie 中以供重用。问题是我们的 SSL 证书适用于 https://secure.example.com ,而我们的网站是 http://www.example.com - 所以我无法从 www.example.com 访问 secure.example.com cookie。
坏主意#2
我的下一个想法是通过 URL 参数将其加密和签名从 HTTPS 登录传递到 HTTP 登录后页面,如下所示:
http://www.example.com/processLogin?key=[encryptedKey]&sig=[encryptedSig]&user=[userid]
加密 key 和加密签名都将使用另一个仅针对该交易存在的私钥进行加密。它将在登录时创建并分配给数据库中的该用户。在 HTTP 端,所有这些都被传递到服务器,该服务器对其进行解密、验证签名、删除该私钥(以防止重放攻击 - 本质上是 nonce )并返回解密的私钥([encryptedKey ]
解密)。
从那时起,[encryptedKey]
的解密值将用于以后的所有交易。问题是解密后的私钥必须通过 HTTP 线路发送,这很糟糕。
坏主意#3
我还短暂地想到 JavaScript 中有一个硬编码 key ,用于解密该值,但无论我如何尝试混淆它,它都可能被黑客找到并使用。
坏主意#4
我也考虑过某种 key exchange在初始握手时使用公钥加密,但如前所述 elsewhere ,除非通过 SSL,否则您无法在客户端真正确信初始握手期间不会发生篡改 - 让我回到第一个方向。
大问题
那么,如果一切都不通过 HTTPS,你们如何管理这些事情呢?我是否必须为 HTTP 和 HTTPS 使用相同的域名,以便可以将此私钥存储在 cookie 中?
请注意,网站的非 SSL 部分不会共享信用卡或登录信息等。我只是不想让这个 SCSS 敞开心扉。
最佳答案
如果不实现 SSL,就无法在 javascript 客户端和服务器之间进行安全且加密的通信。是不可能的。如果您真正想要完成的不是加密流量,而只是确保与您交谈的客户端已被授权发出请求并且该客户端不是冒充者,那么 OAuth 可能就足够了。请参阅http://www.dotnetopenauth.net/用于标准 OAuth .net 实现。
如果 OAuth 不是您想要参与的内容,而您只是想在已经构建的内容的基础上进行构建,则应该向 javascript 客户端分发 token 以及公钥和私钥。公钥和 token 是针对每个请求来回发送的内容,而私钥永远不会来回发送,而是用于生成某种类型的签名哈希。每个请求都应具有此签名和基于时间的随机数以防止重播。您还应该经常使 token 过期,并要求客户端使用其签名和公钥请求“刷新” token 。本质上,我所描述的是 OAuth 1.0a,如果您确实想走这条路,我会引用 DotNet OpenAuth,而不是尝试自己尝试。
但是,重申一下,如果没有 SSL,您仍然容易受到其他类型的攻击。此外,除非您对初始 token 请求进行 SSL 加密,否则黑客总是可以嗅探 token /公钥/私钥对的初始交付,因此,消除了您为确保安全而付出的所有努力。
上述方法的替代方法是在客户端和 REST API 之间设置代理服务器。对API的请求只能通过代理服务器。客户端登录并从https://secure.example.com获取cookie使用基本身份验证。然后,客户端继续向 secure.example.com 发出请求,secure.example.com 然后向您的 API 发出请求并将数据返回给客户端。
无论如何,希望有足够的信息让您深思。
关于javascript - 维护 https 和 http 之间的私钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12077099/