简体   繁体   English

Java(JJWT)对Base64的解码不同

[英]Base64 decoded differently in Java (JJWT)

I have a JWT token generated by some service and then being verified on my Java application. 我有一些服务生成的JWT令牌,然后在我的Java应用程序上进行了验证。

The problems is that JJWT library fails to parse JSON header due to wrong decoding of base64. 问题在于,由于对base64的错误解码,JJWT库无法解析JSON标头。

Header Base64 code: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InRva2VuLXNpZ25pbmcifQ 标头Base64代码: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InRva2VuLXNpZ25pbmcifQ

Decoded by JJWT (boils down to calling: new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(myBase64), java.nio.charset.Charset.forName("UTF-8"))) ): 由JJWT解码(归结为调用: new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(myBase64), java.nio.charset.Charset.forName("UTF-8"))) ):

{"alg":"RS256","typ":"JWT","kid":"token-signing"

So the last curly brace is lost. 因此,最后一个花括号丢失了。

However when I tried ше with other decoder ( https://www.base64decode.org/ ) - the last curly brace is in place. 但是,当我尝试使用其他解码器( https://www.base64decode.org/ )时,最后一个花括号就位了。

Also for other developer the same code used to work. 对于其他开发人员,也可以使用相同的代码。

Can it be something environment specific which influences Base64 decoding in Java? 可能是特定于环境的东西会影响Java中的Base64解码吗?

The header you received is Base64 without output padding (note that there are 66 characters, which is not a multiple of 4). 您收到的标头是没有输出填充的 Base64(请注意,有66个字符,不是4的倍数)。 DatatypeConverter.parseBase64Binary is specified to parse the XML Schema xsd:base64Binary type, which requires output padding . 指定DatatypeConverter.parseBase64Binary来解析XML Schema xsd:base64Binary类型,该类型需要输出padding Apparently it treats the non-padded characters at the end as invalid and simply ignores them. 显然,它将末尾的未填充字符视为无效,而只是忽略它们。

Either use a different decoder (Java 8 has java.util.Base64 , Apache Commons.Codec has one , Guava has one too ), or pad the output yourself (if length of string after removing all non-Base64 characters is not divisible by 4, pad with '=' until it is). 使用其他解码器(Java 8具有java.util.Base64Apache Commons.Codec具有1Guava也具有1 ),或者自己填充输出(如果除去所有非Base64字符后的字符串长度不能被4整除) ,用'='填充,直到它为止。

The header and payload of a JWT is base64 url encoded , which is slightly different than base64 (replaces + , \\ with - , _ and removes trailing = ) 一个JWT的头和有效载荷是base64编码的URL,这是比BASE64略有不同(替代+\\- _并删除尾随=

Using this code DatatypeConverter.parseBase64Binary to decode the header is wrong. 使用此代码DatatypeConverter.parseBase64Binary解码标头是错误的。 It is needed to use: 需要使用:

java.util.Base64.getUrlDecoder().decode(string);

I have reviewed the code of JJWT and decodes the header in the correct way. 我已经检查了JJWT的代码,并以正确的方式解码了标头。 Look at DefaultJWTSParser line 255 查看DefaultJWTSParser第255行

String origValue = TextCodec.BASE64URL.decodeToString(base64UrlEncodedHeader);

May be you are using other library? 可能您正在使用其他库?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM