我有一些服务生成的JWT令牌,然后在我的Java应用程序上验证。
问题是由于base64的解码错误,JJWT库无法解析JSON头。
标题Base64代码:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InRva2VuLXNpZ25pbmcifQ
由JJWT解码(归结为:
new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(myBase64), java.nio.charset.Charset.forName("UTF-8")))
):
{"alg":"RS256","typ":"JWT","kid":"token-signing"
所以最后一个花括号丢失了。
然而,当我尝试使用其他解码器(https://www.base64decode.org/)时,最后一个大括号已经到位。
同样对于其他开发人员来说,使用相同的代码。
是否可能是特定于环境的因素影响Java中的Base64解码?
答案 0 :(得分:1)
您收到的标题是Base64 without output padding(请注意,有66个字符,不是4的倍数)。指定DatatypeConverter.parseBase64Binary
来解析XML Schema xsd:base64Binary
类型,requires output padding。显然,它将末尾的非填充字符视为无效,只是忽略它们。
使用不同的解码器(Java 8具有java.util.Base64
,Apache Commons.Codec has one,Guava has one too),或者自己填充输出(如果删除所有非Base64字符后的字符串长度不是可被4整除,用' ='填充,直到它为止。
答案 1 :(得分:1)
JWT的标头和有效负载是 base64 url encoded ,这与base64略有不同(用+
替换\
,-
,{{ 1}}并删除尾随_
)
使用此代码=
解码标头是错误的。需要使用:
DatatypeConverter.parseBase64Binary
我已经查看了JJWT的代码并以正确的方式解码了标头。查看DefaultJWTSParser第255行
java.util.Base64.getUrlDecoder().decode(string);
您可能正在使用其他图书馆吗?