16

我喜欢使用脚本包含使用 Google Maps 的 API 的方式,但我很担心:

我的 api 是“半私有的”,也就是说,可以通过互联网访问,但应该允许数据的安全传输和某种身份验证。数据应该通过网络保持私有,一个消费者不应该能够获取另一个消费者的数据。

如何使用 SSL 和某种身份验证来确保数据安全,但仍可从纯 HTML 页面“水平”访问,而无需服务器端代理?我需要管理密钥吗?如何将密钥发布到服务器而不被拦截?我可以使用 OpenId(或其他一些 3rd-party 身份验证)来验证 api 用户,还是必须创建自己的身份验证机制?我一直在使用 Google,但找不到安全设计和部署 API 的好指南。

现在我正在使用 REST 和 AJAX 来使用它们,但是跨域调用是不可能的。任何帮助或正确方向的指针将不胜感激。

4

5 回答 5

10

我可能会使用带有 SSL URL 的动态生成的脚本标签,该标签在查询字符串中包含一个公钥加密的密钥。服务器将使用私钥解密查询字符串参数并返回包含相关信息的脚本(如果密钥无效,则不返回)。或类似的规定。但我承认我实际上并没有在实践中这样做。

我还会寻找现有技术,例如亚马逊的 S3 服务。

所以:

  1. 用户提供秘密
  2. 客户端代码使用公钥加密秘密
  3. JavaScript 附加一个script包含 URL 的标签
  4. 服务器处理脚本请求,解密秘密,检查它,然后发回相关响应。

您可能需要两个周期,否则可能会通过中间人攻击重新使用对服务器的请求。那将是:

  1. JavaScript 附加一个script请求唯一密钥的标签(可能带有一些混淆信息,如源 IP 和一些随机的进一步密钥)
  2. 服务器使用与该 IP 绑定的一次性密钥进行响应
  3. 用户提供秘密
  4. 客户端代码使用公钥加密秘密,包括来自#1 的唯一密钥
  5. JavaScript 附加一个script包含 URL 的标签
  6. 服务器处理脚本请求,解密秘密,检查它,然后发回相关响应。
  7. 可以使用#1 中包含的随机密钥对响应进行加密(在某种程度上)

我实际上都没有做过。(或者我有吗?BWAa-ha-ha-ha...) FWIW。

于 2010-10-30T22:36:22.410 回答
0

查看开源 javascript Forge 项目。它提供了一个允许安全跨域 xhr 请求的 javascript TLS 实现。它可能对您有用:

http://digitalbazaar.com/2010/07/20/javascript-tls-1/

http://digitalbazaar.com/2010/07/20/javascript-tls-2/

https://github.com/digitalbazaar/forge

一种可能的解决方案:

  1. 设置 Apache 服务器来运行您的站点。
  2. 为您的站点获取 SSL 证书。
  3. 安装 Forge 附带的 apache mod 以设置允许其他站点访问您的跨域策略。
  4. 在您的站点上托管 Forge 的 TLS 实施以及 PEM 格式的站点证书。
  5. 告诉其他站点包含您站点中的 javascript,并使用它对您的站点进行安全调用,以执行您想做的任何事情。
于 2010-11-08T16:48:56.543 回答
0
  1. (第 3 方)页面使用 OAUTH 或类似的东西来验证用户并从您的服务器获取令牌。
  2. 页面通过 SSL 从您的服务器加载 IFRAME,传递令牌以进行身份​​验证。
  3. IFRAME 可以通过 SSL 安全地与您的服务器通信
  4. 使用easyXDM或类似的东西在 IFRAME 和第 3 方页面之间进行通信,使用您创建的一些有限的类似 RPC 或类似套接字的 API。

或者,如果您真的不信任第三方 - 在 iframe 内进行身份验证(然后不需要 oauth,只需使用普通的 html 表单)并使用 easyXDM 传达外部页面需要了解的有关用户的任何信息。

于 2010-11-11T11:35:40.260 回答
0

OAuth 可以通过让用户登录到第 3 方应用程序并允许您的应用程序在您发出 xhr 请求时使用请求令牌代表他们访问第 3 方来帮助解决这种情况。http://oauth.net/documentation/getting-started/

========

使用服务器端代理的原因归结为 Web 浏览器内置的同源策略:http ://en.wikipedia.org/wiki/Same_origin_policy

本质上,浏览器只允许向页面来源地址发出请求(例如,facebook.com 只能向 facebook.com URI 发出请求)。服务器端代理通过向当前源之外的服务器发出请求来解决此问题。服务器端代理也是发出此类请求的最佳实践。

于 2010-11-07T19:17:44.550 回答
0

不太清楚问题到底是什么,我认为您正在尝试对 [https://secure.com] 进行类似 jsonp 的调用,以便在 [http://regular.com] 上处理/显示数据]?

两台服务器可以互相通信吗?像这样的东西怎么样:

  1. 用户登录 [https://secure.com]

  2. 身份验证后,secure.com 生成一个令牌(我们称之为 syntoken)并将其直接传递给 regular.com(服务器到服务器),可能像 session_id、一些任意消息和一个 otp 密码(我们称之为同步密码) .

  3. Broswer 收到 session_id cookie,然后 Secure.com 将浏览器重定向到http://regular.com/setcookieandredirect?session_id=blabla&otpencryptedsynmessage=blabla

  4. Regular.com 使用 session_id 作为密钥查找 otp 密码,并解密 otpencryptedmessage “blabla”。

  5. 如果解密后的消息与 syntoken 中的原始消息匹配,我们可以验证用户是否登录 [regular.com],然后 regular.com 生成另一个令牌(我们称之为 acktoken,lolz)并将其直接传递给 [secure.com],包括session_id、一些任意 ack 消息和不同的 otp 密码(我们称之为 ackcipher)。

  6. 然后,Regular.com 向浏览器发送一个由 otpencryptedackmessage 组成的 cookie(让我们将此 cookie 命名为“verified_session”)。

  7. 完成页面加载。

从那里,您可以进行类似 jsonp 的调用

https://secure.com/getscript.js?query=dataname&verifiedtoken=(verified_sessions_cookie_value )

其中secure.com/getscript.js 将获取verifiedtoken,根据[secure.com] 发送的原始cookie session_id 作为密钥查找ackcipher,并解密otpencrypedackmessage。如果解密的消息与 ack 消息匹配,则渲染脚本文件。

这有点像 3 次握手。秘诀在于服务器必须能够直接相互通信才能离散地传递密钥。您不必为两台服务器使用相同的 session_id,我只是将其用作一个简单的参考点,以找到一种访问 syn/ack otp 密码的方法。密码必须完全不公开。

于 2010-11-13T12:06:01.637 回答