从您的问题看来,您正试图通过服务器 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 在评论中提到的那样,如果 B 首先的可信度有限,那么允许 B 收集您的用户的凭据是非常不明智和不安全的。此外,我做出这个假设是因为使用第三方来托管您的 Web 应用程序是一项常见任务,例如 Heroku、Amazon 等,它们不会是恶意的(如果他们这样做,他们会失去大量的业务,而且他们几乎一无所获。此外,如果您检测到安全违规行为,您会有人追究责任。因此他们可以被信任,或者您一开始就不会使用它们)。我现在假设你不是使用像他们这样的第三方来源,因为情况似乎很明显。
如果 B 可能是恶意的,那么无论您对客户端代码做什么,B 都可以更改它并拦截凭据。只要可以信任 B 不会修改您的客户端代码,那么我之前的建议就会奏效。但是,鉴于 B 的可信度有限这一新信息,实施我之前的建议是不明智的。
通过不受信任的第三方对您的服务的用户进行身份验证是一项非常危险的工作,正如 PayPal 构建 API 所花费的金额所表明的那样。但是,如果您必须这样做,那么您将需要非常小心,并考虑实施类似于 PayPal 的解决方案。
如果您必须通过第三方,那么类似于上面评论中提到的@halfer 的解决方案就是要走的路,IMO。
[P]也许您应该单击 B 中的某些内容,它会重定向到 A,从您的站点获取用户许可,然后使用身份验证令牌重定向回 B。这样做的好处是,您不会鼓励用户在他们不应该绝对信任的站点中输入他们的主密码。
让用户使用 HTTPS/TLS/SSL重定向到您的站点。这可以保护用户的凭据,并且还可以向用户验证您的身份,这样他们就不太可能陷入域名欺骗攻击。然后,您可以向第三方提供足够随机的令牌以用作身份验证。
但请理解,即使使用此解决方案,仍然存在重大风险。如果 B 想要攻击您的用户,B 仍然可以通过直接询问他们的登录凭据来轻松欺骗他们中的一部分。这可能对他们中的大多数人不利,他们不精通安全。
如果 B 不被信任,那么我的专业建议是不要这样做。