4

他们中的许多人对如何编写安全的 rest web 服务感到困惑,对于那些对使用哪种方法感到困惑的人来说,这篇文章会很有帮助。

编写 REST 服务的可能方式(部分安全)

  • 您意识到通过 HTTP 传递凭据会导致数据以纯文本形式被嗅探;在 Gawker 事件之后,您意识到纯文本或弱散列的任何内容通常都是一个坏主意。

  • 您意识到散列密码并通过线路发送散列代替纯文本密码仍然可以让人们至少嗅探帐户的用户名和密码的散列,可以(在令人不安的情况下)被查看在彩虹表中。

  • 您惊呼,因为在这种情况下(这实际上是一个用户名/密码场景),您仍然会遇到与以纯文本形式发送用户名和密码相同的问题(嗅探流量)。

  • 在这一点上,您即将放弃并承认使用OAuth,但您坚持必须有一种安全但相对简单的方法来设计可以保持凭据私有的公共 Web API。

4

1 回答 1

4

最佳解决方案

服务器和客户端知道公钥和私钥;只有服务器和客户端知道私钥,但每个人都可以知道公钥……谁在乎他们知道什么。客户端创建一个唯一的 HMAC(哈希)来表示它对服务器的请求。它通过组合请求数据(参数和值或 XML/JSON 或它计划发送的任何内容)并将请求数据的 blob 与私钥一起散列来实现这一点。然后客户端将该 HASH 连同它本来要发送的所有参数和值一起发送到服务器。服务器获取请求并使用客户端使用的相同方法根据提交的值重新生成它自己的唯一 HMAC(哈希)。服务器然后比较两个 HMAC,如果它们相等,则服务器信任客户端,并运行请求。

示例说明:( 假设您从 android 发送此请求,因为 android 应用程序大多是无会话的,它们无法使用 cookie 或任何内容来记住哪个用户已登录。因此,对于这种情况,当请求与它还需要用户凭据。)

  • 必须发出请求的网站(在这种情况下,我使用的是 localhost):localhost:8080/
  • 用户 X 的 URL REST 请求: localhost:8080/REST/books/favorites(假设响应是用逗号分隔的纯文本 [Harry Potter, Chandamama, Infinitethoughts, Twilight])。
  • 由于必须显示用户 X 信息,因此请求将如下所示: localhost:8080/REST/username/Password/books/favorites - localhost:8080/REST/X/abc/books/favorites

这里的问题是用户名和密码可以被嗅探,因为它们是纯文本..所以,最好在客户端加密它们并在服务器端解密它们。

现在实际问题出现了,服务器如何知道发送的请求是否由有效的客户端发送......

  • 解决方案是生成您的 URL 请求的哈希并将该哈希添加到 URL 的末尾,然后将请求发送到服务器。(我们通常说的是校验和).. 使用您自己的或使用基于 java 的哈希生成器(如 SHA1、MD5 等)生成校验和

  • 假设为 URL 请求 localhost:8080/REST/encrypted-username/encrypted-Password/books/favorites 生成的哈希是一些哈希字符串 adasfsjimnom123123k。因此,将其添加到您的 URL

本地主机:8080/REST/加密用户名/加密密码/书籍/收藏夹/adasfsjimnom123123k

因此,通过这种方式,您可以保护 Web 服务请求。只有当生成的校验和有效时,服务器才会提供请求的详细信息。

使用 Curl 工具作为休息客户端(而不是单独的 java 代码)来测试您的服务。

完整参考

于 2012-10-23T06:59:38.187 回答