解码不等于验证
前两段是 base64url,只是一种编码,不是一把锁:任何拿到令牌的人都能读出其中的每一条声明,不需要密钥,也不需要任何技巧。载荷本身没有加密,假装它加密了,正是令牌里最终会塞进本不该出现的数据的原因。
签名提供的是来源,而不是保密性。它是一个只有签发方才能产出的值,因此校验签名的一方能确认:这些声明出自持有密钥的人之手,并且自签署以来没有改动。页面之所以把两种解读分开,就是为了这个:令牌说了什么,以及签名是否与你给出的密钥匹配。
这一族里最古老的漏洞是 `alg: none`,即令牌宣称自己未签名。相信头部的校验方会满足任何人的任何要求,所以面板把这种情况当作风险发现来处理,而不是客客气气地解码。第二种是头部自带密钥(`jwk`、`jku`、`x5u`):从令牌里取密钥的校验方,实际上是在拿令牌验证它自己。