【问题标题】:JSON Web Token and the year 2038 bugJSON Web Token 和 2038 年错误
【发布时间】:2018-08-19 14:35:20
【问题描述】:

JSON Web Token 是一个相当新的标准(2015 年 5 月),但他们决定使用 UNIX timestamps 以便 represent dates

这不会在各种实现中将标准暴露给潜在的Year 2038 problem 吗?相反,选择ISO8601 之类的东西似乎更有前途。

为什么选择一个高于另一个?

【问题讨论】:

  • 我认为因为 UNIX 时间戳并不总是存储为 32 位值,RFC 依赖于这样一个事实,即到 2038 年,大多数机器将在 64 位值上运行。通过使用 64 位值,问题被推迟到非常非常远的地方
  • @ArthurAttout 这就是确切的问题。为什么要冒险而不是使用其他数据类型?

标签: timestamp jwt iso8601 year2038


【解决方案1】:

JSON 对数字的精度没有限制,因此 JWT 格式本身没有溢出问题。这一切都取决于实现。

某些实现(例如 JavaScript)将所有 JSON 数字视为双精度浮点数。虽然直到宇宙热死之后它们才会溢出,但它们将在不到 3 亿年的时间里开始变得不准确,并且随着时间的推移问题会变得更糟(比如你创建一个令牌1 小时后过期,但该值不能表示为双精度浮点数,最接近的值是 2 小时后,所以直到 2 小时后才过期。

其他实现可能使用 64 位有符号整数。这些将在 3000 亿年后溢出,远在太阳变成红巨星并吞噬地球之后。

唯一易受 Y2038 问题影响的实现是在解析日期时决定使用 32 位有符号整数的实现。这样的实现将是愚蠢的。不管你选择什么格式,你都无法防止愚蠢——ISO8601在这里没有任何帮助,因为虽然这可能是在线上出现的,但每一个实现都会将它解析成一些时间自某个时代以来的单位,因为这是所有计算机处理日期的方式,并且是实际进行计算的唯一方法,例如令牌是否已过期。因此,即使使用 ISO8601,每个实现都容易选择精度低的数字表示来处理特定时间之后的日期,包括选择带符号的 32 位整数来表示自 1970 年以来的秒数,这是 Y2038 问题.由每个实现选择一个适当大小的数字类型来表示它们的解析日期,您可能会发现它们都这样做(如果没有,您应该报告一个错误)。

所以,不,JWT 使用自 UNIX 纪元以来的秒数作为日期没有任何问题。

【讨论】:

  • 我真的很喜欢阅读这篇文章。使用 64 位有符号整数,“这些将在 3000 亿年后溢出,远在太阳变成红巨星并吞噬地球之后。”是我希望我能在这个行业更经常说的话。
【解决方案2】:

Unix 时间戳并没有那么糟糕——它们绝对可以帮助您简化一堆计算,而不是解析日期。

在大多数情况下,JWT 中的日期声明应该与 NOW() 进行比较(想想 exp 声明),因此在那里使用时间戳是有意义的。

我不会担心 Y2038 错误,因为 32 位系统会比发布 JWT 存在更大的问题。

【讨论】:

    猜你喜欢
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 2019-01-21
    • 1970-01-01
    • 2014-08-19
    • 2011-01-02
    相关资源
    最近更新 更多