安全的跨域身份验证表单

时间:2013-05-08 22:25:49

标签: php security cross-domain forms-authentication

我有一台服务器'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吗?

1 个答案:

答案 0 :(得分:0)

从你的问题来看,听起来你正试图通过服务器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被信任不会恶意企图获取用户的凭据。我做了这个假设,因为正如评论中提到的那样,如果B首先具有有限的可信度,那么允许B收集用户的凭证是非常不明智和不安全的。此外,我做了这个假设,因为使用第三方来托管你的网络应用程序是一项常见的任务,例如Heroku,亚马逊等,他们不会是恶意的(如果他们这样做,他们将失去大量的业务,并且他们如果你发现安全违规,你就有责任追究责任。因此,他们可以信任,或者你不会在第一时间使用它们。我现在假设您使用像他们这样的第三方来源,因为看起来很明显就是这种情况。

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

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

如果你必须通过第三方,那么类似于上述评论中提到的@halfer的解决方案是要走的路,IMO。

  

[P]很可能你应该点击B中的某些内容,它会重定向到A,获取   来自您网站的用户权限,并使用。重定向回B.   认证令牌。这样做的好处是你不鼓励   用户在他们不应该访问的站点中输入他们的主密码   绝对信任。

让用户使用HTTPS / TLS / SSL 重定向到您的网站。这可以保护用户的凭据,还可以验证用户的身份,从而降低域欺骗攻击的可能性。然后,您可以向第三方提供足够随机的令牌以用作身份验证。

但请理解,即使使用此解决方案,仍存在重大风险。如果B想要攻击你的用户,B仍然可以通过直接询问他们的登录凭证来轻松欺骗他们中的一部分。这可能会对他们中的大多数人起作用,他们并不擅长安全。

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