我正在为用户可以跟踪费用的基本应用程序开发REST api。我想处理身份验证,其中用户首先使用其凭据(电子邮件+密码)提交请求,并获得包含可与进一步请求一起使用的访问令牌的响应(因此他们不必发送其用户密码每一次)。
原始回复还包括一个秘密"盐。"每次用户使用给定令牌提交请求时,该令牌都将变为无效,并且必须通过散列与第一个响应中返回的秘密盐一起使用的最后一个令牌来生成新令牌。
我需要为所有连接提供HTTPS。
这里的想法是,即使攻击者以某种方式获得了使用的令牌,他们也无法使用该令牌,因为a)它可能已过期/消耗而b)他们不会使用该令牌。知道原始回复中返回的秘密盐。最终,秘密+令牌组合到期,用户将不得不重新输入凭据并获得新的秘密+哈希对。
这是一个额外的过程,每次都有一个秘密,甚至值得吗?我在这里获得了额外的安全保障吗?或者我只是过度复杂化而没有真正的好处?
示例:
获取令牌:
curl -i -X GET -H 'Content-Type: application/json' \
-d '{"email":"test@test.com", "pass":"test"}' \
https://api.example.com/accesstoken
返回{token,secret_salt,expires}的回复。客户端 可以忘记用户+传递,只保留秘密和最多 最近的令牌,现在。
获取一些数据:curl -i -X GET
https://api.example.com/users/123?t=TOKEN_A
返回带有用户数据的响应
令牌。现在,令牌被消费了#34;而且不再有效。用户必须生成新的
令牌TOKEN_B = sha1(TOKEN_A + secret_salt)
。他们可以
在新请求中使用此新令牌。
获取更多数据:curl -i -X GET https://api.example.com/expenses/123?t=TOKEN_B
现在消耗了TOKEN_B,他们必须生成另一个令牌。
最终,secret_salt到期,用户必须这样做 输入凭据并获取新凭证。
答案 0 :(得分:2)
首先,你必须考虑你想要保护谁。
通信通道是https,它被认为是安全的防范窃听和中间人攻击。如果攻击者可以绕过这种级别的保护,他可能会访问盐甚至用户凭据。滚动令牌不会增加任何额外的保护。
如果攻击者可以访问客户端计算机,他将可以访问秘密盐和最新令牌,如果客户想要提出另一个请求,则必须存储这些令牌。与不更改的令牌相比,滚动令牌在这种情况下也不会添加任何额外的安全性。
如果攻击者只能拦截一个传输的消息,滚动令牌可能会保护您。在这种情况下,他将收到的令牌将毫无用处。但是,有可能绕过https保护并拦截一条消息的人也可以看到所有通信。
如果滚动令牌提供的额外保护很小,那么它增加的额外复杂性非常高。要求客户端和服务器具有同步令牌意味着同步可能会在某个时间中断,并且用户必须使用其凭据再次进行身份验证。要求用户更频繁地进行身份验证会带来更大的安全风险,这对用户体验也有害。
总结我认为滚动令牌添加的可能的额外安全性并不能证明额外的复杂性。具有一些过期策略的静态令牌就足够了。
答案 1 :(得分:1)
我们在一年前遇到了同样的问题,并决定采用这种单一令牌/ NONCE方法。 上个月,由于复杂性的增加和这种方法的问题,我们回到了更长寿命的令牌。
首先是因为异步发送多个请求时出现问题。如果您不能确保请求按给定顺序排列,请不要使用单一用途令牌。使用给定的技术,您在排队请求时会限制自己,我想。
但您仍然可以使用此salt方法,并使用来自salt + request-params
的客户端创建的哈希验证您的响应。从我的角度来看,这会增加与您的方法相同的安全级别。