【问题标题】:Secure cross-domain authentication form安全跨域认证表单
【发布时间】:2013-05-03 07:23:59
【问题描述】:

我有一个服务器“A”。你有一个服务器'B'。服务器“A”想要向服务器“B”提供登录表单(用户名和密码)。

如何实现服务器“B”无法查看/拦截用户填写的内容的场景?凭据必须以安全的方式到达服务器“A”而不被拦截。

这可能吗?

这是一个更好的例子:

服务器 A 向服务器 B 提供服务,服务器 B 向具有服务器 A 的密码。在某些时候,用户必须在服务器 A 中进行身份验证,但登录表单将显示在服务器的 B 页面中。我清楚了吗?服务器 B 无法读取这些凭据。

业务逻辑是服务器 A 有许多客户端,服务器 A 将允许第三方开发应用程序到服务器的 A 客户端。拥有主密码的是服务器 A,而服务器 B 无法访问/读取/拦截这些凭据。在服务器 B 上对客户端进行身份验证的方式是通过嵌入在服务器 B 中的登录表单(我无法将用户重定向到服务器 A。用户必须停留在服务器的 B 页面上。)。

问题是:

将表单嵌入服务器 B 的更好方法是什么?

服务器B能否运行能够在提交前读取用户凭据的 JavaScript?

【问题讨论】:

  • 我没有server,它只是服务器(你)和客户端(我们)。而保护中间人攻击的唯一 100% 方法是 ssl/https。
  • 我认为他是说他希望能够在服务器 B 上放置一个登录表单,该登录表单发布到服务器 A,但不允许访问服务器 B 上发布的数据。就像某人的方式使用站点 A 的凭据登录站点 B。听起来像是 openid 的实现或类似 google/facebook 登录的东西。
  • 你可以在没有 SSL 的情况下做到这一点,方法是从服务器 A 发布到自己,然后使用共享密钥加密,然后使用 cURL 联系服务器 B。但是,从用户到服务器 A 的路径在技术上仍然是容易被拦截。您能否提供更多关于您要保护的内容的背景信息?
  • 也许 A 应该实现二级密码或 API 密钥。或者也许您应该单击 B 中的某些内容,它会重定向到 A,从您的站点获取用户许可,然后使用身份验证令牌重定向回 B。这样做的好处是,您不会鼓励用户在他们不应该绝对信任的网站中输入他们的主密码。

标签: php security cross-domain forms-authentication


【解决方案1】:

从您的问题看来,您正试图通过服务器 B 传递敏感数据,但 B 不是最终目的地。即使B是目的地(或来源),答案还是一样的

执行此操作的方法是使用 HTTPS/TLS/SSL。这将使用 A 的公共证书加密数据,这样数据只能通过 A 的私钥解密,只有 A 拥有。

这还提供了向客户端验证 A 身份的额外好处。 A 提供了一个用 A 的私钥签名的证书。只有 A 的公钥才能正确解密它,从而证明只有 A 可以生成该证书(或者有人窃取了它,但我们假设情况并非如此)。

编辑:

为此,让 B 提供页面但无法读取其数据,让 B 提供的网页在客户端使用 Javascript 加密数据,并使用 A 的公钥(可以包含在页面中由 B)。即使 B 有 A 的公钥,它也无法解密 JS 加密的数据。它只能将其传递给 A。

编辑:

只要在客户端使用 A 的公钥完成所有加密,数据将不会被 A 以外的任何方读取,因为只有 A 的私钥才能解密它。使用这种方法,您可以在没有风险的情况下拥有任意数量的中介。*

*这当然假设 RSA 密钥对具有足够的熵和长度以被认为是安全的。至少 1024 位,最好是 2048 位。

又一次(也是最后一次)编辑:2013 年 5 月 9 日

很抱歉进行了多次修改,但您的问题让我感到困惑。我想我现在明白你在问什么了。

在我之前的帖子中,我做了一个重要的假设,那就是服务器 B 被信任不会恶意尝试获取用户的凭据。我做出这个假设是因为,正如 halfer 在 cmets 中提到的那样,如果 B 首先的可信度有限,那么允许 B 收集您的用户的凭据是非常不明智和不安全的。此外,我做出这个假设是因为使用第三方来托管您的 Web 应用程序是一项常见任务,例如 Heroku、Amazon 等,它们不会是恶意的(如果他们这样做,他们会失去大量的业务,而且他们几乎一无所获。此外,如果您发现安全违规行为,您会有人追究责任。因此他们可以被信任,或者您一开始就不会使用它们)。我现在假设您没有使用像他们这样的第三方资源,因为情况似乎很明显。

如果 B 可能是恶意的,那么无论您对客户端代码做什么,B 都可以更改它并拦截凭据。只要可以信任 B 不会修改您的客户端代码,那么我之前的建议就会奏效。但是,鉴于 B 的可信度有限这一新信息,实施我之前的建议是不明智的。

通过不受信任的第三方对用户进行身份验证是一项非常危险的工作,这从 PayPal 构建 API 所花费的金额可以看出。但是,如果您必须这样做,那么您需要非常小心,并考虑实施a solution similar to PayPal

如果您必须通过第三方,那么类似于上面评论中提到的@halfer 的解决方案是可行的方法,IMO。

[P]也许你应该点击 B 中的某个东西,它会重定向到 A,得到 来自您网站的用户许可,并使用 身份验证令牌。这样做的好处是你不鼓励 用户在他们不应该在网站中输入他们的主密码 绝对信任。

让用户使用 HTTPS/TLS/SSL 重定向到您的网站。这可以保护用户的凭据,并且还可以向用户验证您的身份,这样他们就不太可能陷入域名欺骗攻击。然后,您可以向第三方提供足够随机的令牌以用作身份验证。

不过,请理解,即使采用这种解决方案,仍然存在重大风险。如果 B 想要攻击您的用户,B 仍然可以通过直接询问他们的登录凭据来轻松欺骗他们中的一部分。这可能对他们中的大多数人不利,因为他们不精通安全。

如果 B 不被信任,那么我的专业建议是不要这样做

【讨论】:

  • 但是我会在 iframe 或类似的东西中嵌入一个表单到服务器“B”中,服务器“B”有没有办法读取用户填写的数据?这些数据很敏感!
  • 如果 B 没有 A 的私钥,那么没有 B,无法读取数据(使用 A 的公钥加密)。如果加密例程由于某种原因失败,请确保您的 JS 例程不会以明文形式提交数据。我不知道现有的库,因此您可能必须自己编写代码。不过应该不难。
  • 假设我在发送前使用jcryption 加密我的表单数据。服务器“B”可以创建一个 javascript 来捕获表单数据吗?嵌入表单的最佳方式是使用 iframe?
  • jcryption 看起来很酷。使用 jcryption,如果您使用 A 的 RSA 公钥加密您的表单数据(而不是协商 B 可以嗅探的 AES 密钥),然后通过使用 A 的 RSA 私钥解密来解密 A 上的提交,那么您会很好。使用这种方法,无论哪种方式,iframe 都可以。
  • @Freedom:好帖子。看起来 OP 可以设置密钥,就像 Twitter 第三方系统一样(例如,被授权自动推文的 Wordpress 插件)。正如您所说,如果需要用户身份验证,服务器 B 可以提供一个表单以重定向到 A,A 签署请求并在获得所需的权限和/或凭据后再次重定向回来。 +1
猜你喜欢
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
相关资源
最近更新 更多