利用JSON Web密钥集扩展JWT验证
上一篇文章中,我们学习了JSON Web令牌(JWT)的概念、创建方法和验证方式。第二部分则演示了如何在简单的Express服务器中使用JWT验证中间件。本篇将深入探讨非对称加密算法,特别是RS256算法,并重点介绍JSON Web密钥集(JWKS)。
术语解释
在开始之前,先了解以下几个关键术语:
JWKS的优势
第二部分中,我们演示了根据令牌的alg声明和环境变量或公钥来验证对称或非对称算法。本部分将专注于非对称算法,特别是RS256。
使用公钥/私钥对的优势在于,验证过程无需私钥离开签名服务器。公钥可以公开,且无法反向推导出私钥。因此,公钥可在任何地方加载,从而实现任何地方的令牌验证。
然而,如果定期轮换公钥(强烈建议这样做),就会出现一个短暂的窗口期,导致证书不匹配:服务器使用新的私钥签名令牌,而验证端点仍持有旧的公钥,导致验证失败。JWKS提供了一种更优的密钥轮换管理方法。
当发行系统签署JWT时,用于签名的私钥的kid(密钥ID)包含在令牌的头部。验证系统读取alg和kid,并使用具有相同kid的公钥验证签名。JWKS是一个JSON对象,包含一个或多个包含其kid的公钥。令牌头部包含kid声明:
{ "alg": "rs256", "typ": "jwt", "kid": "12345" }
kid可以是任何字母数字字符串。JWKS包含一个密钥数组,每个密钥对象如下:
{ "kty": "RSA", "use": "sig", "kid": "12345", "n": "...", "e": "..." }
请注意每个密钥都有一个kid;令牌头部必须包含相同的kid才能加载正确的公钥。 n和e包含构建公钥所需的信息。库如jsrsasign可以导入这些信息并构建用于验证令牌的公钥。
JWKS的访问和更新
虽然JWKS提供了多密钥管理的序列化格式,但手动更新多个端点上的JWKS仍然很麻烦。更好的策略是利用自动发现,将密钥集托管在一个已知的URI上,以便客户端可以定期自动更新。例如,Microsoft Azure AD将其JWKS存储在https://www.php.cn/link/7153f307b5c0c430849e99573d3f3176。 当需要轮换密钥时,只需将新的公钥添加到集合并重新发布JWKS即可。客户端定期轮询URI获取最新的公钥。
密钥生成
前面提到了公钥/私钥对。您可以自己生成,但通常不建议使用自签名密钥,因为某些云提供商和验证软件包不允许使用。 建议使用Let's Encrypt生成签名的密钥。
首先,确保已安装并更新Certbot。然后,使用以下命令生成2048位RSA私钥:
certbot certonly \ --manual \ --preferred-challenges dns-01 \ --key-type rsa \ -d jwks01.yourdomain.com
Certbot会提供一个TXT记录,需要将其添加到_acme-challenge.jwks01.yourdomain.com。(子域名称可自定义)。验证后,Certbot会在默认位置(例如/etc/letsencrypt/live/jwks01.yourdomain.com)生成四个文件。我们主要关注privkey.pem(RSA私钥)和fullchain.pem(证书签名链)。将这两个文件复制到项目目录。
使用以下命令从私钥生成公钥:
openssl rsa -in privkey.pem -pubout -out pubkey.pem
您现在拥有签名的RSA私钥及其对应的公钥。 下一部分将介绍如何修改之前的Express-JWT示例,以导入这些密钥,在已知的URI上提供JWKS服务,并使用JWKS验证由不同私钥签名的多个令牌。
进一步阅读:
以上就是边缘零信任(第3部分)的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号