验证 JWT 令牌签名
Posted
技术标签:
【中文标题】验证 JWT 令牌签名【英文标题】:Verify JWT Token Signature 【发布时间】:2019-11-01 22:47:52 【问题描述】:我目前正在使用 Vapor 开发 Swift 后端。我的 ios 客户端使用新的 iOS 13 功能“使用 Apple 登录”。当用户登录时,我得到一个身份令牌(访问令牌),它是由 Apple 签名的有效 JWT 令牌。这将在所有正在进行的通信中发送到服务器,以验证服务器提供的某些路由。
在服务器上,我想通过验证令牌签名来验证发送的令牌确实是由 Apple 签名的,并且不是由某些恶意用户专门制作的。 Apple 提供了一个 HTTP 端点来检索公钥来执行此操作:Apple Documentation。
但是我不确定我必须多久查询一次此端点以从 API 检索模数和指数并构建公钥然后验证签名。 查询一次并将公钥存储在服务器上以使用它是否足够,或者我需要在验证签名之前查询中间件中的 HTTP 端点(对于每个受保护的路由)?
基本上我不确定模数和指数是否会不时改变。
【问题讨论】:
jwt.io 列出了所有流行语言的 JWT 验证库。 为什么要更改公钥? @user28434 我知道如何验证签名,我不确定公钥可能多久更改一次。 @LutzHorn 我不确定。由于密钥不在我的控制范围内,我想谨慎行事,因为当密钥更改时,我的服务器将不再工作,因为无法验证所有令牌。但是,如果我只能生成一次密钥并在我的服务器上使用它,那就太棒了,因为这意味着没有不必要的 http 请求并减少了我的开销。 如果你使用苹果服务,你必须使用他们的公钥。那么“生成一次密钥”是什么意思?如果您不控制发布 JWT 的服务,您就无法控制密钥。 【参考方案1】:你可以这样做:
获取一次公钥,将其存储在您的服务器上 请求进来,尝试使用存储的公钥验证签名 如果失败,再次获取公钥并存储它 再次尝试验证签名这将使您能够在必要时立即了解更改的公钥。
【讨论】:
这显然是解决问题的好方法。非常感谢:) 再补充一点,假设有十个用户的 JWT1 使用 key1 签名。然后苹果将他们的密钥更改为 key2。然后说其他十个用户使用 key2 签署了他们的 JWT2(此时您的系统中仍然有 key1)。现在假设用户使用 JWT2,那么您的验证将失败,您将从苹果获取公钥并重试,这将检查出来。现在假设有 10 个用户向您发送 JWT1,这意味着您最终会从苹果获取 10 次并且每次都失败。因此,您可能希望将从苹果获得的所有各种密钥存储在数据库本身中以上是关于验证 JWT 令牌签名的主要内容,如果未能解决你的问题,请参考以下文章