2012-06-14 257 views
6

我有一个Web服务,我提供给用户使用我的应用程序数据库并获取一些信息。用户必须注册一个API密钥并在提出请求时提供该密钥。一切正常,但我如何检查注册密钥的用户是否实际提出请求,而不是他可能提供密钥的其他人?REST Web服务和API密钥

我一直在想过去两天想出一个解决方案,但没有到目前为止。

+0

你使用JAVA或PHP(或其他)吗? – sp00m

+0

服务器端语言为PHP – slash197

+0

@Laurent回答说,您可以查看OAuth processus,但我会建议使用OAuth2。即使帖子有点老了,你会发现[这里](http://stackoverflow.com/q/4875420/1225328)该机制的PHP实现。 PS:Google和Facebook都使用OAuth2让开发人员与他们的API进行通信。 – sp00m

回答

10

您需要使用已签名的请求。基本上,它的工作原理类似:

  • 你给你的用户的API密钥一个“秘密”(一个随机字符串),只有你和客户知道。
  • 无论何时他们提出请求,他们都会为其添加“签名”参数。该签名基本上是请求参数+ API密钥+其他参数(见下文)+秘密的散列。
  • 既然你也知道秘密,你可以验证签名是否正确。

为了避免重放攻击,您还可以在混合中添加乱数和时间戳。一个随机数只是一个数字,必须由客户端在每个请求中增加。当你收到请求时,你会检查你是否已经收到了这个nonce/timestamp。如果你这样做,你会拒绝这个请求(因为这很可能是重播攻击)。如果不是,则将nonce/timestamp存储在数据库中,以便稍后查看它。

这是或多或少如何请求OAuth。看看他们在链接中的例子。

+0

谢谢!听起来很有趣,我必须检查一下。 – slash197

+0

如果用户放弃了他们的密钥,无论如何您都无法正确验证他们的身份。政策(而不是技术)必须规定适当使用API​​密钥和密钥。尽管如此,这是很好的信息。在什么情况下会应用重放攻击 - 流量嗅探(API键/参数)还是猜测请求参数? – KyleM

+0

@KyleM,是的,它是为了防止MITM攻击。如果连接是通过https连接的(我们猜测它并不重要)。 –

2

有2个部分用于认证REST API调用。当用户注册您的服务时,您通常会分配一个标识该用户的KEY。有时候,这就够了。但是这个KEY可以被共享或被盗。在这种情况下,您的服务仍然会将KEY视为有效。现在,为了防止关键劫持等,您还将分发一个密钥。此密钥绝不会随REST API请求一起传输。此密钥用于执行API请求的单向散列,并创建签名(HMAC)。

此签名加上API请求(URL形式的HTTP请求)然后发送到API服务器。服务器执行URL的单向散列,并使用该用户的私钥与签名进行比较。如果它们匹配,则“假定”请求者有权访问私钥,因此该请求是有效的。

为了避免重放攻击,除了nonce(如上一张海报所示),您还可以使用散列链接。