RSA JWT 密钥轮换周期?
RSA JWT key rotation period?
我已经创建了一个基本的 JWT 生成器,但需要一些方面的建议。我一直在使用 JWT.io 's guides and the auth0/java-jwt libraries/repo 来生成令牌。
正在使用 2 个不同的密钥对 JWT 进行签名。
正在使用 4096 位密钥使用 RSA512 算法对刷新令牌进行签名。
.sign(Algorithm.RSA512(rsaPublicKey, rsaPrivateKey));
正在通过 RSA256 算法使用 1024 位 RSA 密钥对访问令牌进行签名。
.sign(Algorithm.RSA256(rsaPublicKey, rsaPrivateKey));
我已经按照 "speed" 上的建议进行了此操作,因为 4096 位验证过程需要更长的时间,但似乎刷新令牌的请求较少,安全性的权衡似乎是公平的。
另一方面,访问令牌在资源服务器端点进行验证,并且它们的发送频率更高,因此我选择了一个较短的 (256) 签名,它使用更快的 1024 位密钥进行预制。
我知道钥匙 "practically" 无法破解...但建议钥匙轮换?
我将 jks(密钥库)保存在身份验证服务器和资源服务器上的私人文件夹中。
密钥库包含 2 个密钥对,一个用于刷新令牌 sign/verify,另一个用于访问令牌 sign/verify。
我需要 refresh/form 新密钥吗?如果是这样……多久一次?
推荐的方法是什么?
负载均衡器后面可以有多个身份验证和资源微服务实例...所以 RAM 生成的密钥是不行的,因为它们不会在实例之间传播。
我看过可能有一个 "key-server" 可以说创建新密钥并将它们附加到密钥库并分发新的 jks 文件以使用新密钥对更新...类似于此:
因此,例如,每隔 15 秒,EC2 身份验证服务器和资源服务器就会 ping 密钥服务器,请求当前 jks 的副本(和版本检查)。
有什么建议吗?
谢谢!
JWT RSA 密钥大小调整
将 RSA 密钥更正为 2048 位,这是当前推荐的大小(2020 年)。
1024 位 RSA 密钥被认为是弱密钥,在处理高度机密信息时已被 NIST 禁止使用。 (提示:中央认证系统是保密的)。只要有足够的计算能力,它就可以被破解,记住任何大型组织都无法访问具有 10k+ CPU 的数据中心。
4096 个密钥是可能的,但验证速度可能比 2048 个慢 10 倍(复杂性与大小不成线性关系)。仔细考虑性能影响。身份验证令牌将在任何地方使用并经过无数次验证。
参见 What RSA key length should I use for my SSL certificates?
上的相关回答
JWT 密钥轮换
假设在 OpenID Connect (OIDC) 中使用 JWT。
活动的 JWT public 密钥可以从 OIDC 服务器获取,在像 /.well-known/keys
这样的端点上。请参阅您的 OIDC 服务器的文档。
应用程序应在启动时检索 public 密钥并定期刷新它们。没有关于多久一次的正式标准?
- 通常的做法是在 1 小时到 1 周之间定期检索密钥。
- 定期自动重启的应用程序(Web 容器)可能会在启动时加载密钥,并且在 运行 期间不会主动刷新它们。
- 服务器通常有一个预定的重启周期(可能是每月或每季度),对重启时间设置上限运行。
- 一个例子:Apache 插件 mod_auth_openidc retrieves keys hourly by default. Setting OIDCUserInfoRefreshInterval
现有令牌在其签名密钥轮换时失效,如果应用程序没有跟上更新的签名密钥,则不接受新令牌。因此,要使事情顺利进行,需要考虑一定的范围。
- 通常的做法是在 1 到 12 个月之间定期轮换密钥。
- Okta 提供 their examples 90 天密钥。
- 像 Facebook 这样的网站几乎从不要求用户重新进行身份验证(几个月?几年?您是否曾经不得不重新登录?),因此那里的签名密钥必须持续数月,而银行网站则不需要支持多个月的会话。
- 比每月更频繁地轮换密钥通常没有意义。它仅突出显示软件未经常重新加载的细微问题,并阻止 "long" 会话。
我个人的建议是确保最大的安全性和最小的麻烦,我已经为大型组织中数千个系统中的数千个应用程序管理了单点登录。
- 签名密钥有效期为 1 年。
- 签名密钥每 6 个月轮换一次。
- 意味着
/.../keys
始终至少有 2 个密钥可用。一个有效密钥和一个待替换的未来密钥。
- 好处:
- 这使应用程序有足够的时间来获取下一个密钥(6 个月),无论是通过主动刷新还是被动重启。
- 6 个月足够长,可以将密钥硬编码到 libraries/applications 中以用于需要它的特殊用例。例如,我们有类似 HPC 的计算集群一次部署 10000 个 tasks/processes,如果它们中的每一个都试图在启动时远程获取密钥,那可能会对 OIDC 服务器进行 DDoS 攻击。
- 必须经常轮换(6 个月绝对最高)才能工作和测试任何东西。如果开发人员执行了一些集成并且没有很好地处理轮换,它会在 6 个月内崩溃并且他们可以修复它(希望仍处于测试阶段或用户有限)。如果轮换发生在 2 年后,没有人会注意到它会坏,直到它坏了并且没有人来修复它,所有原始开发人员早已离开。
DDoS
顺便说一下,时间线从来都不是以秒为单位的,这个问题提到秒很有趣。
公司的一切都依赖于身份验证系统,当 "everything"(数千个服务)每隔几秒(甚至几分钟)尝试 ping 同一个服务时,这是一种快速的方法了解永久性意外 DDoS 的概念。
JWT 的主要目标之一就是不需要中央服务来验证令牌(大量持续加载的单点故障)。您可以通过在启动时仅远程加载一次签名密钥来实现限制依赖项的目标(假设您 运行 定期重启的服务)。
我已经创建了一个基本的 JWT 生成器,但需要一些方面的建议。我一直在使用 JWT.io 's guides and the auth0/java-jwt libraries/repo 来生成令牌。
正在使用 2 个不同的密钥对 JWT 进行签名。
正在使用 4096 位密钥使用 RSA512 算法对刷新令牌进行签名。
.sign(Algorithm.RSA512(rsaPublicKey, rsaPrivateKey));
正在通过 RSA256 算法使用 1024 位 RSA 密钥对访问令牌进行签名。
.sign(Algorithm.RSA256(rsaPublicKey, rsaPrivateKey));
我已经按照 "speed" 上的建议进行了此操作,因为 4096 位验证过程需要更长的时间,但似乎刷新令牌的请求较少,安全性的权衡似乎是公平的。
另一方面,访问令牌在资源服务器端点进行验证,并且它们的发送频率更高,因此我选择了一个较短的 (256) 签名,它使用更快的 1024 位密钥进行预制。
我知道钥匙 "practically" 无法破解...但建议钥匙轮换?
我将 jks(密钥库)保存在身份验证服务器和资源服务器上的私人文件夹中。 密钥库包含 2 个密钥对,一个用于刷新令牌 sign/verify,另一个用于访问令牌 sign/verify。
我需要 refresh/form 新密钥吗?如果是这样……多久一次? 推荐的方法是什么?
负载均衡器后面可以有多个身份验证和资源微服务实例...所以 RAM 生成的密钥是不行的,因为它们不会在实例之间传播。
我看过可能有一个 "key-server" 可以说创建新密钥并将它们附加到密钥库并分发新的 jks 文件以使用新密钥对更新...类似于此:
因此,例如,每隔 15 秒,EC2 身份验证服务器和资源服务器就会 ping 密钥服务器,请求当前 jks 的副本(和版本检查)。
有什么建议吗?
谢谢!
JWT RSA 密钥大小调整
将 RSA 密钥更正为 2048 位,这是当前推荐的大小(2020 年)。
1024 位 RSA 密钥被认为是弱密钥,在处理高度机密信息时已被 NIST 禁止使用。 (提示:中央认证系统是保密的)。只要有足够的计算能力,它就可以被破解,记住任何大型组织都无法访问具有 10k+ CPU 的数据中心。
4096 个密钥是可能的,但验证速度可能比 2048 个慢 10 倍(复杂性与大小不成线性关系)。仔细考虑性能影响。身份验证令牌将在任何地方使用并经过无数次验证。
参见 What RSA key length should I use for my SSL certificates?
上的相关回答JWT 密钥轮换
假设在 OpenID Connect (OIDC) 中使用 JWT。
活动的 JWT public 密钥可以从 OIDC 服务器获取,在像 /.well-known/keys
这样的端点上。请参阅您的 OIDC 服务器的文档。
应用程序应在启动时检索 public 密钥并定期刷新它们。没有关于多久一次的正式标准?
- 通常的做法是在 1 小时到 1 周之间定期检索密钥。
- 定期自动重启的应用程序(Web 容器)可能会在启动时加载密钥,并且在 运行 期间不会主动刷新它们。
- 服务器通常有一个预定的重启周期(可能是每月或每季度),对重启时间设置上限运行。
- 一个例子:Apache 插件 mod_auth_openidc retrieves keys hourly by default. Setting OIDCUserInfoRefreshInterval
现有令牌在其签名密钥轮换时失效,如果应用程序没有跟上更新的签名密钥,则不接受新令牌。因此,要使事情顺利进行,需要考虑一定的范围。
- 通常的做法是在 1 到 12 个月之间定期轮换密钥。
- Okta 提供 their examples 90 天密钥。
- 像 Facebook 这样的网站几乎从不要求用户重新进行身份验证(几个月?几年?您是否曾经不得不重新登录?),因此那里的签名密钥必须持续数月,而银行网站则不需要支持多个月的会话。
- 比每月更频繁地轮换密钥通常没有意义。它仅突出显示软件未经常重新加载的细微问题,并阻止 "long" 会话。
我个人的建议是确保最大的安全性和最小的麻烦,我已经为大型组织中数千个系统中的数千个应用程序管理了单点登录。
- 签名密钥有效期为 1 年。
- 签名密钥每 6 个月轮换一次。
- 意味着
/.../keys
始终至少有 2 个密钥可用。一个有效密钥和一个待替换的未来密钥。 - 好处:
- 这使应用程序有足够的时间来获取下一个密钥(6 个月),无论是通过主动刷新还是被动重启。
- 6 个月足够长,可以将密钥硬编码到 libraries/applications 中以用于需要它的特殊用例。例如,我们有类似 HPC 的计算集群一次部署 10000 个 tasks/processes,如果它们中的每一个都试图在启动时远程获取密钥,那可能会对 OIDC 服务器进行 DDoS 攻击。
- 必须经常轮换(6 个月绝对最高)才能工作和测试任何东西。如果开发人员执行了一些集成并且没有很好地处理轮换,它会在 6 个月内崩溃并且他们可以修复它(希望仍处于测试阶段或用户有限)。如果轮换发生在 2 年后,没有人会注意到它会坏,直到它坏了并且没有人来修复它,所有原始开发人员早已离开。
DDoS
顺便说一下,时间线从来都不是以秒为单位的,这个问题提到秒很有趣。
公司的一切都依赖于身份验证系统,当 "everything"(数千个服务)每隔几秒(甚至几分钟)尝试 ping 同一个服务时,这是一种快速的方法了解永久性意外 DDoS 的概念。
JWT 的主要目标之一就是不需要中央服务来验证令牌(大量持续加载的单点故障)。您可以通过在启动时仅远程加载一次签名密钥来实现限制依赖项的目标(假设您 运行 定期重启的服务)。