JWT技术疑问咨询:密钥定义、跨服务校验及jwt.io验证原理
关于JWT工作机制(尤其是签名部分)的答疑
嘿,我来帮你理清这几个关于JWT签名的核心问题——刚接触JWT时,这几个点确实容易让人困惑,咱们一个个说:
问题1:签名是否是仅认证服务器知晓的密钥(非用户密码),类似服务器的私钥?
没错,但这里要分两种加密算法场景来看:
- 对称加密算法(比如HS256):签名用的是一个共享密钥,这个密钥只有认证服务器和需要验证JWT的服务(比如你的应用服务器)知晓,和用户的登录密码完全无关。认证服务器用这个密钥生成签名,验证方用同一个密钥来校验签名是否合法。
- 非对称加密算法(比如RS256):这里用的是密钥对——认证服务器用自己的私钥生成签名,而验证方只需要持有对应的公钥就能校验签名。私钥只有认证服务器自己保管,公钥可以公开给所有需要验证JWT的服务。
无论哪种情况,签名用的密钥都和用户密码没有任何关系,是服务器端专门用于JWT签名验证的密钥。
问题2:若使用独立的应用服务器与认证服务器,应用服务器收到客户端的JWT后,是否需要将其发送至认证服务器进行验证?我认为应用服务器因不知晓签名所用密钥,无法自行验证JWT。
这得看你用的是哪种签名算法,以及系统的配置:
- 如果是对称加密(HS256):只要应用服务器和认证服务器共享了签名密钥,那应用服务器完全可以自己本地验证JWT,不用发回认证服务器。
- 如果是非对称加密(RS256):应用服务器只要拿到认证服务器发布的公钥,就能自己校验签名的合法性,同样不需要和认证服务器交互。
只有在一些特殊场景下(比如JWT的密钥频繁变动、或者你用了OAuth2的令牌 introspect 端点来做额外校验),才需要把JWT发回认证服务器验证。大部分常规场景下,应用服务器都可以独立完成JWT的验证工作。
问题3:我将以下JWT粘贴至jwt.io,看到‘Signature Verified’提示。jwt.io在未知晓密钥的情况下,如何确认签名正确?
先看你提供的JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxLS9tSjVsVTNYc09QWCt2VitpaGZRMWlCUDVjUTROQm1hNDluOE9rS1FFSnEzTDFNOTl2VW9iQ1ZLUHVYMmdlWWhYaHJQM0t3bHY4SE1RaHNGdnFjbllIeGxGSHM9IiwiaXNzIjoicGxheS1zaWxob3VldHRlIiwiZXhwIjoxNTI2MjgxMDU1LCJpYXQiOjE1MjYyMzc4NTUsImp0aSI6IjhmOGM3YTVmYWRkNTE5MjUxNzQ5NGE4N2Q1ODcxZjJjZGUxZDkzMDdkOTY1MThjNjg2NzExOTc1YjU3M2I5NDBlZWU2NGY0NDUwYzcxODI3NGZmNzU1MmE2Y2JlNTVmZmZhMWI1ZjA3ZWZlOWVkNTE0Y2Y4YTViOTZlM2ExYjI0ODRmYTI5NjZiYjA0ODlmODIwZjMyMzM5YWVhNjM3NWRkZmU4ZDE4N2E2NzBjMzg0ODgwZGIyMzQ1ZTFkMzRkYWNjZmY2MTdkMDY1NzU3YmEwZTQzNDg4YWFhZmZmNDNjYWZlZGY0OTFlODU1YTA0NWM0NmJjNDY4NGYzODlmY2YifQ.GwN6TSNd426xpc3Y02eRXHbrmSr_61MMBqrmx66Ofqs
观察这个JWT的头部,它用的是HS256算法(alg":"HS256),而这个JWT的签名是用空字符串作为密钥生成的。jwt.io默认会先用空字符串尝试验证HS256类型的JWT,刚好这个JWT的签名就是用空密钥生成的,所以就显示“Signature Verified”了。你可以看一下对应的验证界面:

这种用空密钥生成JWT的情况是非常不安全的,属于错误配置,任何拿到这个JWT的人都能随意篡改载荷再用空密钥重新签名,完全失去了JWT签名的意义。
内容的提问来源于stack exchange,提问作者Manu Chadha
相关产品推荐
相关产品推荐

