如何在不使用OAuth的情况下制作安全API?

时间:2015-07-28 10:54:43

标签: php api security amazon-web-services hash

我的要求

我正在制作一个也有移动版的网站。所以,我正在以API为中心。现在我想在没有OAuth复杂性的情况下使我的API安全,因为我需要的安全性非常简单。我不希望任何有权访问api链接的人能够访问我的数据。

所以,我偶然发现了这篇文章http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/,这篇文章非常令人惊讶并清除了我的大部分疑虑。

现在,我正在尝试重新创建文章中的内容。我正在使用Laravel 5框架进行PHP开发。

我想确保移动应用和网络版仅使用API​​,而不是其他任何人。 我见过像

这样的api链接
example.com/fetchallinformation&publicKey=<something>&Hashkey?<some_hash_key>

现在,我知道这个密钥是通过在php中使用hash_hmac()函数生成的。

我的方法

  • 我有一个表格,我为我的api用户存储了publicKey和privateKey
  • URL中的HashKey是通过在客户端散列privateKey和publicKey生成的,然后发送到服务器。因此,我将生成的Hash与publicKey一起发送到服务器。
  • 在服务器端,我使用publicKey和Hash。我从对应于publicKey的表中检索私钥并拥有它们并检查结果哈希是否与客户端发送的哈希相同
  • 如果相同,那么我允许他们,否则,我不会。

我的困惑

  • 我不确定这是否是正确的方法。

  • 我们可以通过解密哈希来获取使用hash_hmac()生成哈希的数据吗?

3 个答案:

答案 0 :(得分:3)

That HashKey in the URL is generated by hashing the privateKey and the publicKey in the client side and then sent to the server. So, i send the generated Hash along with the publicKey to the server.

Close, but not quite. As you just described it, a user with a given public key would send the same hmac with every request. That's no better than "username and password."

Side note: if you aren't using https, you're already insecure and whatever else you do to secure the site is of relatively little value.

The point of generating an hmac signature is that it not only authenticates the user as being in possession of the secret key, it also authenticates the specific request as being made by that user and being made during a specific window of time. Two different requests back to back should have a different hmac. One request today and an identical request tomorrow should also have a different hmac. Otherwise, you're in for replay attacks. This means information about the current time or expiration time of the signature, and information about the request itself, must be included in the information that's passed through the hmac algorithm or you're not accomplishing much.

For any given request, by a specific user, at a specific time, there can only be one possible valid signature. HMAC is not reversible, so you can't take the signature apart at the server end and figure out the attributes of the request.

Of course, of you're thinking about embedding that secret key in your app, remember that such tactics can be relatively trivial to reverse-engineer.

Is it a viable authentication mechanism? Of course. As the article points out, Amazon Web Services uses hmac signatures on their APIs, and they have a massive potential attack surface... but does that mean you will implement it in a meaningfully secure fashion? Not necessarily. There is always someone more clever, devious, and determined than you can imagine.

Even Amazon apparently realizes that their Signature Version 2 is not as strong as it could be, so they now have Signature Version 4, which has a much more complex algorithm, including several rounds of hashing and generation of an intermediate "Signing Key" that is derived from your secret, the current date, the specific AWS service, AWS region, and other attributes. Regions where Amazon S3 was first deployed in 2014 or later don't have support for the original Sig V2 at all -- and it seems like it can only be security-consciousness that drove that decision, since the old algorithm is computationally less expensive, by far.

Use caution in rolling your own security mechanisms.

If you are primarily trying to avoid the learning curve with OAuth, which I agree is quite annoying at first, you could be on a fool's errand.

答案 1 :(得分:0)

如果这种方法适合你,它肯定会很好,毫无疑问它是安全的。

关于解密 - 由于其性质(哈希),HMAC不应被解密。 HMAC被认为是非常安全的,你应该没有问题。您可以阅读更多关于How and when do I use HMAC? [SE Security]

的信息

答案 2 :(得分:0)

  

我想确保移动应用和网络版仅使用API​​,而不是其他人。

这是一个问题,OAuth和AWS风格的签名身份验证都无法提供帮助。两者都是关于验证用户,而不是应用程序。如果你有一大堆时间沉入其中,你当然可以实施任何一种方法,但在这两种情况下你都需要嵌入一个秘密&#34;在你的应用程序中,一旦你将该应用程序提供给用户,你的秘密就不再是秘密...

没有什么好方法可以做你正在寻找的事情。如果有人花时间对您的应用进行逆向工程,以了解如何直接点击底层API,那么您在客户端进行的任何其他操作都需要进行身份验证&#34;调用应用程序也可以进行逆向工程。

我建议不要打扰,并花时间节省您的应用程序,以便没有人想要绕过它并直接点击您的API。 :)