【问题标题】:What's the point of a timestamp in OAuth if a Nonce can only be used one time?如果 Nonce 只能使用一次,那么 OAuth 中的时间戳有什么意义?
【发布时间】:2011-10-15 11:50:27
【问题描述】:

一开始我误解了 OAuth 的时间戳实现,认为这意味着一个不在当前时间之后 30 秒内的时间戳将被拒绝,结果证明这是错误的,原因包括我们可以不保证每个系统时钟都足够同步到分钟和秒,无论时区如何。然后我又读了一遍以更清楚:

"除非服务提供者另有规定,否则时间戳为 以自 1970 年 1 月 1 日 00:00:00 GMT 以来的秒数表示。 时间戳值必须是正整数并且必须等于或 大于之前请求中使用的时间戳。”

来源:http://oauth.net/core/1.0/#nonce

意味着时间戳仅与来自同一来源的先前请求进行比较,而不是与我的服务器系统时钟进行比较。

然后我在这里阅读了更详细的描述:http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/

TL;DR? - 跳到下面的粗体部分)

为防止再次使用(重放)受损请求, OAuth 使用随机数和时间戳。术语nonce的意思是“使用的数字 一次'并且是一个唯一且通常是随机的字符串,旨在 唯一标识每个签名的请求。通过拥有唯一标识符 对于每个请求,服务提供者都能够阻止请求 被多次使用。 这意味着消费者生成一个 发送给服务提供者的每个请求的唯一字符串,以及 服务提供者跟踪所有用于防止它们的随机数 避免被第二次使用。 因为 nonce 值包含在 签名,攻击者不能在不知道签名的情况下更改它 共享秘密。

根据服务提供商的需求,使用 nonce 的成本可能非常高 永久存储收到的所有随机数值。做 实现更简单,OAuth 为每个请求添加一个时间戳值 这允许服务提供者只保留随机值 有限的时间。 当请求带有较早的时间戳时 超过保留的时间范围,作为服务提供者被拒绝 不再有该时间段的随机数。 可以安全地假设 在允许的时间限制之后发送的请求是重放攻击。身份验证 提供了实现时间戳的通用机制,但离开 到每个服务提供者的实际实施(一个领域很多 相信应该由规范重新审视)。从证券 从观点来看,真正的 nonce 是时间戳值的组合 和随机数字符串。只有结合在一起,它们才能提供永恒的独特价值 攻击者永远无法再次使用。

我感到困惑的原因是,如果 Nonce 只使用一次,为什么服务提供商会根据时间戳拒绝? “服务提供商不再拥有该时间段的随机数”让我感到困惑,听起来好像可以重复使用随机数,只要它在 最后一次使用的 30 秒内。

那么任何人都可以为我解决这个问题吗?如果 nonce 是一次性使用,并且我没有将时间戳与我自己的系统时钟进行比较(因为这显然不可靠),那么时间戳的意义何在。时间戳只会相互关联是有道理的,但对于唯一的随机数要求,它似乎无关紧要。

【问题讨论】:

    标签: oauth unix-timestamp nonce


    【解决方案1】:

    时间戳用于允许服务器优化其随机数的存储。基本上,将读取的 nonce 视为时间戳和随机字符串的组合。但是通过拥有一个单独的时间戳组件,服务器可以使用一个短窗口(比如 15 分钟)实现基于时间的限制,并限制它需要的存储量。如果没有时间戳,服务器将需要无限的存储空间来保存所有使用过的 nonce。

    假设您决定允许您的时钟与客户的时钟之间存在最多 15 分钟的时差,并且正在跟踪数据库表中的 nonce 值。该表的唯一键将是“客户端标识符”、“访问令牌”、“随机数”和“时间戳”的组合。当有新请求进来时,检查时间戳是否在时钟的 15 分钟内,然后在表中查找该组合。如果找到,拒绝呼叫,否则将其添加到您的表中并返回请求的资源。每次向表中添加新的 nonce 时,请删除时间戳超过 15 分钟的“客户端标识符”和“访问令牌”组合的任何记录。

    【讨论】:

    • 那么我只是每 6 小时清除一次 Nonce 表,始终确保 Nonce 只使用一次,并且传入的时间戳大于或等于最后一次成功使用的请求时间戳。那正确吗?这样,如果他们尝试重新使用 Nonce,它将失败,但如果他们等待 6 小时并尝试使用请求,它仍然会失败,因为时间戳会比上次发出的请求更早?然后再一次,如果请求从未通过,那么它可以再次使用......所以我不明白这将如何阻止重放攻击。
    • 您需要保持滚动队列,而不是每 6 小时清空一次。您所做的是保留每个给定客户端标识符的所有 nonce 值的列表,并在其时间戳大于您的窗口(例如 15 分钟)时从队列中逐出值。如果请求的时间戳早于您的窗口,您会直接拒绝它,否则,您会在队列中查找时间戳+nonce,如果未找到,则提供受保护的资源。
    • 我想知道我会将这个队列存储在哪里,或者它是否只是“内置”到我用来从 nonce 表中拉回的查询中?对于每个给定的客户端标识符,您是什么意思?我目前使用 AccountID 存储 Nonce,但如何区分“队列中”的 Nonce 和“表中”的 Nonce?
    • 您将其与您的时间戳进行比较,并且应该允许最多 15 分钟的时钟偏差。如果客户端的时钟偏离时间超过 15 分钟(当然是 GMT),您应该返回一个错误,告诉客户端进行同步。如果您的开发人员编写基于桌面或浏览器的应用程序,他们应该使用时间服务来满足应用程序时间戳的需求,而不是本地时钟。此外,如果您不需要重放保护,则可以完全忽略 nonce。今天,Twitter 会检查 nonce,而 Yahoo 和 Google 则不会。
    • @eran-hammer 如果我们坚持每个后续时间戳都必须大于该用户的前一个时间戳,我们还需要一个随机数吗?
    【解决方案2】:

    好的,经过深思熟虑,我相信我已经破解了这个。

    他们希望我始终知道最后一次成功请求的时间戳,这样如果在此之前出现任何时间戳,它将被忽略。

    Nonce 也必须是唯一的,但我只会将它们存储到某个日期范围内,因此如果时间戳记这么多小时,Nonce 将被删除,然后可以再次使用,但是因为最后一个使用过的时间戳也被存储,即使 Nonce 被认为是唯一的,它们也不能重用旧请求,因为该请求上的时间戳会过时。

    但是,这只适用于签名。如果他们更改了请求中的时间戳或 Nonce,则签名将不再与请求匹配并且将被拒绝(因为时间戳和 Nonce 都是签名创建的一部分,并且它们没有签名密钥)。

    呼!

    【讨论】:

      【解决方案3】:

      如果 OAuth 只使用时间戳,攻击者就可以相对容易地猜出下一个时间戳是什么,并将他们自己的请求注入到进程中。他们只需要执行“前一个时间戳 + 1”。

      通过使用以加密安全方式生成的随机数(希望如此),攻击者不能简单地注入 TS+1,因为他们没有适当的随机数来验证自己。

      将其视为需要钥匙卡和 PIN 码的安全门锁。你可以偷钥匙卡,但仍然无法通过门,因为你不知道密码。

      【讨论】:

      • 你错过了这个问题。我理解nonce,但是如果nonce只能使用一次,我看不到时间戳的附加值。
      • 可能是数据包丢失了。一次可能有多个随机数“在飞行中”。时间戳是为了保证事物的顺序。
      • 一个nonce一旦被消耗就不能再次使用,它们是独一无二的
      【解决方案4】:

      可以合理地假设人们可以尝试用蛮力破解随机数。时间戳会降低某人成功的机会。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-06
        • 1970-01-01
        • 2016-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多