1

我设计了一个 REST 授权服务,它的工作方式与Amazon S3 REST 身份验证非常相似,并且它足够安全,可以在 HTTP 上工作(不需要让所有互通在 SSL 上运行的开销)。

它足够安全,因为签名在每次请求时都会更改并且会过期。所以它对 MITM(不能编辑任何东西,否则端点将无法重新生成相同的签名)和重放攻击(因为时间戳的使用)是安全的。

这对所有客户端都有好处,因为知道私钥,现在可以对自己的数据执行请求的操作,生成包含请求数据的唯一签名。

授权服务不生成任何令牌(因此它不会受到 MITM 攻击)并且仅在内部调用,这意味着客户端直接向正确的端点执行请求以执行某些操作,而不是请求令牌以提供该服务......然后接收该请求的端点向授权服务询问“嘿,这个请求合法吗?” 如果是,则授权服务返回“200 OK”并执行请求的操作,否则返回“401 Unauthorized”。

我现在需要的是允许一个特殊的客户端,一个 Web 用户界面,让用户使用电子邮件/密码登录,并使用 WebUI 本身来获取/编辑他们的数据。webUI 将在 HTTPS 上运行。请考虑创建一个新帐户总是会生成用户/密码登录和 pubkey/privatekey,但实际上我们只使用 pubkey/privatekey。用户和密码存储在仅由 WebUI 使用的数据库中,而 pubkey/privatekey 存储在授权服务(使用另一个数据库)中。

当然,要处理客户数据,我需要一些方法来使 webUI 充当为登录用户编写的客户端(具有 pubkey/privatekey 关联对来生成签名)。我不确定什么是最安全的方法,所以我将解释几个我坚持的解决方案。

我认为的第一个解决方案是为 Web 界面提供自己的 pubkey/privatekey,使其成为真正的客户端,然后编辑授权服务以识别它并允许它使用像“X-Forwarded-For”这样的标头)并始终信任 WebUI 权限。但我害怕不知何故我错过了一些可能导致攻击利用此权限获取您未授权的数据的东西。

第二种解决方案是,一旦成功登录,将 pubkey/privatekey 从授权服务传输到 WebUI,然后将其存储在会话中,每次执行操作时,它都会使用该数据生成有效签名。但我真的不喜欢通过网络传递这些数据(也因为这种通信至少应该通过 SSL 以避免被嗅探到私钥),而且我真的不喜欢将私钥存储在会话后端中.

我坚持的最后一个解决方案是重新考虑授权服务,并允许通过用户和密码进行身份验证(这将不再存储在 webUI 中,而是与授权服务中的 pubkey/privatekey 一起存储)。这总是需要 SSL 连接,因为 webui 必须传送电子邮件和密码,但如果正确登录,它只能将这些数据存储在创建的会话中。另一个副作用是其他服务可以实现为使用 user/pwd 而不是使用签名方法,通过 HTTP 意味着向世界公开数据。

我想要最强大、更合乎逻辑的解决方案,使 webUI 充当客户端,因为整个架构被认为是在客户端-服务器的基础上工作的。我也可以接受此处未列出的其他建议。

请告诉我您是否需要了解更多信息来帮助我。

谢谢(如果您已阅读整篇文章:-P)

4

1 回答 1

0

HTTPS

首先,我认为您误解了所有 HTTPS 的东西。使用 HTTPS,您可以提供客户端证书,但在最常见的情况下,仅使用服务器证书。因此,在这种常见情况下,HTTPS 不提供对用户进行身份验证的方式,只提供服务器本身。它还提供消息加密。

如果您使用 HTTP,即使您可以防止真正的 MITM 攻击,任何 MITM 都会看到您的所有消息。如果他们不被保密(一些私人数据等)也许没关系

另一件事是验证服务器本身。据我从您指定的数据中可以看出(可能其中一些丢失或我误解了),所有请求都已签名,但响应未签名(或者它们是)。在这种情况下,您很容易受到 MITM 攻击,因为攻击者可以伪装成您的身份验证服务器。

我建议同时使用 HTTPS 对服务器进行身份验证,并对消息和签名进行编码以对客户端进行身份验证。还要记住,为了防止 MITM 攻击,您还必须使用根 CA 证书检查服务器证书。

私钥

我不太明白您如何向您的客户启动私钥。好吧,从技术上讲-是的,但是私钥是私有的。如果您生成它们,它们不再是私有的。在这种情况下,您可以只生成一些共享密钥并使用一些更简单的算法来签署请求。至少在我看来,当您知道两个密钥都不比共享密钥更安全时,使用 PPK。

另一种方法是允许客户端在生成公钥后将公钥上传到您的服务器。

密码

在我看来,授权服务器应该对授权做出所有决定。因此,我会将密码和公钥(或共享机密)存储在授权服务器中,而不是 UI 部分。

结论

你的情况让我想起了OAuth2 协议。有资源所有者、客户端、授权服务器和资源服务器。资源所有者以某种方式授予对客户端的访问权限,客户端从提供该授权的授权服务器获取访问令牌。然后它使用它来访问资源服务器。

您的系统中可以使用两种授权类型:资源所有者密码凭据授权和客户端凭据授权。

  • 您的资源所有者本身就是客户。
  • UI 也是一个客户端。
  • UI 通过提供客户端的密码凭据来获取访问令牌,然后对资源服务器进行一些调用。
  • 客户端仅通过使用共享密钥或公钥对自己进行身份验证来获取访问令牌。

当然,如果协议不完全适合您的情况,您可以从协议中获取一些想法。

至于签署请求,有MAC访问认证,可以在同一个OAuth2中使用。

所以,我建议将密码存储在授权服务器中,UI 只会传递它们来修改一些资源。不要为客户端生成私钥 - 使用共享密钥或让他们上传公钥。使用 HTTPS 对远程服务器进行身份验证。

于 2013-01-05T12:48:40.417 回答