安全API身份验证方法

SAF*_*FAD 16 security api

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

第一个建议:

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

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

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

第二个建议:

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

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


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

最好的祝福

Jon*_*han 12

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

第一个建议

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

第二个建议

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

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

身份验证阶段(SSL)

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

API请求阶段

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

计算签名

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

分析

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

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

HMAC是众所周知的解决方案.看到:


Jam*_*ess 7

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

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

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

  • 出于多种原因通常避免这种方法.我现在可以回忆一下.1.将正常的用户功能与API访问联系起来.在不撤消其他形式的访问权限的情况下,您无法撤消API访问权限.2.不允许任何类型的权限管理.有时您希望为API提供不同的授权.当然,如果客户端和服务器都在您的控制之下并使用SSL,那么开始使用HTTP Auth应该没问题. (3认同)
  • 我没有看到问题.您的数据库中有一个标志,指出特定用户是否允许API访问 - 如果不允许,您拒绝API访问,但其他一切仍然有效.读/写访问权限也是如此.您没有为某人分配新的用户名和密码,只是因为您已经更改了他们的权限.2.为什么要对API进行不同的授权?这听起来像一个循环论证 - 你不能做X,因为有时候你不想做X. (2认同)

anf*_*fab 5

首先是一些观察

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

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

这两种方法都是有效的并且被广泛使用.所以,如果你不想要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/


aet*_*aet 0

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