安全API身份验证方法

时间:2013-07-18 22:44:42

标签: api security

我们正在开发一个新项目,我们是两个主要的开发人员,并且在如何使用令牌来保护服务器和客户端之间的通信方面走得越来越远:

第一条建议:

步骤一)客户端通过发送用户名和密码以及current_time(此变量将保存在服务器的数据库和客户端也)到api,服务器解释输入和呈现来请求主令牌散列令牌(例如:58f52c075aca5d3e07869598c4d66648)将其保存在数据库中并将其返回给客户端。

步骤二)客户端现在保存主令牌,并使用主令牌+在身份验证请求中发送的current_time变量创建新的哈希令牌(让我们调用此新令牌,main_token)服务器也会这样做并创建同样的算法使用相同的算法。

第三步)每次客户端查询服务器API时,它会将main_token发送到服务器,现在服务器将其中生成的令牌与客户端发送的main_token进行比较,如果匹配,则表示用户是实

第二个建议:

步骤一)客户端生成两个随机密钥($ key1 = rand(10000,90000); $ key2 = rand(10000,90000);)在API上的每个请求中,客户端使用查询类型创建哈希,并使用复杂算法创建两个密钥,并将这两个密钥+哈希值发送到服务器

步骤二)服务器使用客户端中使用的相同算法创建哈希,并与客户端发送的哈希进行比较,如果匹配,则服务器继续处理查询


现在,问题是,哪一个是用于保护api请求的最合理,最安全的方式

最好的问候

4 个答案:

答案 0 :(得分:12)

这两种解决方案都没有任何安全性方面的好处。

第一个建议

一旦我有main_token,我就可以计算任何哈希值(main_token + timestamp)。我需要访问的所有API都是main_token,为什么还要为时间戳业务烦恼呢?

第二个建议

如果您使用每个请求和查询类型发送两个随机数,那么是什么阻止我做同样的事情并使用您的API?算法?加密算法的规则是,如果你自己滚动,有人会破解它。第二条规则是通过默默无闻的安全措施不起作用。

如果您的身份验证过程比您的api更安全,则可以采用其他方式保护呼叫:

身份验证阶段(SSL)

  1. 客户端发送用户/密码并获取一个随机字符串'Secret_token'。
  2. Secret_token存储在客户端和服务器端。
  3. Secret_token永远不会再通过电汇传输。
  4. API请求阶段

    1. 客户端创建请求
    2. 客户端规范化请求
    3. 客户端使用Secret_token
    4. 计算规范化请求的签名*
    5. 客户端将请求+签名发送到服务器
    6. 服务器规范化请求
    7. 服务器使用Secret_token
    8. 计算规范化请求的签名
    9. 如果签名匹配,则服务器继续处理请求
    10. 计算签名

      首先,规范化请求。这可能意味着提取重要参数,包括方法(post,get,action,timestamp)并将它们按顺序排列。然后通过HMAC算法运行该字符串,该算法将Secret_token作为参数。

      分析

      只有在身份验证发生时,才会通过线路传输Secret_token。假设认证过程非常安全(因为在此过程中密码被转移,这是一个安全的假设)。

      注意:通过纯文本发送仍然不安全,请使用SSL。

      HMAC是众所周知的解决方案。参见:

答案 1 :(得分:7)

为什么不在每个请求上使用标准HTTP Auth,因此每次都要通过用户名和密码。然后服务器只是验证该用户名/密码组合而不是令牌。

鉴于您使用SSL / TLS进行连接,因此不存在泄露用户名/密码的风险。并且也不可能对SSL进行重放攻击,因此不需要过期任何东西。

我建议保持简单并使用已经开发的现有协议。在安全方面,你可能不应该试图重新发明轮子,除非你有充分的理由这样做。

答案 2 :(得分:5)

首先是一些观察

  1. 在第一种方法中,令牌基本上成为长期密码。每次请求都会重复使用它。因此,如果此令牌被泄露,您就完成了。并不是说不鼓励,因为OAuth 2就是这样做的,但SSL在这里绝对是强制性的。此外,如果你坚持这一点,你必须确保令牌有一个到期日期和机制,以确保在有妥协的情况下迅速撤销令牌。

  2. 您描述的第二个选项与AWS使用的类似,但没有密钥。这里的优点是,因为它使用查询生成散列,所以散列将随每个请求而改变。因此,如果一个令牌被泄露,您不必担心,因为它不适用于任何其他请求。此外,您可以使用此方法始终检测中间人攻击,因为如果内容被修改,算法将生成不匹配的哈希值。

  3. 这两种方法都是有效且广泛使用的。所以,如果你不想要SSL,那么2就是你要走的路。如果你对SSL很好,那么OAuth是另一种选择。我推荐的实际上是采用其中任何一种技术。如果您正在使用1)那么请查看Oauth2,如果您正在使用2)然后坚持使用AWS计划(严格来说,这不是一个标准,但它被广泛记录)。

    我认为有些链接可能会有所帮助

    http://www.wolfe.id.au/2012/10/20/what-is-hmac-and-why-is-it-useful/

    http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

    http://blog.cloudfoundry.com/2012/10/09/securing-restful-web-services-with-oauth2/

答案 3 :(得分:0)

由于客户端具有在第一个建议中计算第二个令牌所需的所有信息,因此第二个令牌并不比第一个令牌更好(更安全,更安全)。 第二个建议似乎是预共享密钥的一些变化。 这些中的任何一个都可以是足够的安全措施。 就个人而言,我更喜欢一种更像第一种方法的方法,并且一直使用SSL。 可以将令牌视为用户名和密码的替代品,您是否会在每次请求时发送令牌明文? (很多网站都是这样做的。)