Java (JJWT) 中的 Base64 解码不同
Base64 decoded differently in Java (JJWT)
我有一个由某些服务生成的 JWT 令牌,然后在我的 Java 应用程序上进行验证。
问题是由于 base64 解码错误,JJWT 库无法解析 JSON header。
Header 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 解码的特定环境吗?
您收到的 header 是 Base64 without output padding (note that there are 66 characters, which is not a multiple of 4). DatatypeConverter.parseBase64Binary
is specified to parse the XML Schema xsd:base64Binary
type, which requires output padding。显然它将末尾的 non-padded 字符视为无效字符并简单地忽略它们。
要么使用不同的解码器(Java 8 有 java.util.Base64
, Apache Commons.Codec has one, Guava has one too),要么自己填充输出(如果删除所有非 Base64 字符后的字符串长度不能被 4 整除,填充'=' 直到它是)。
JWT 的 header 和负载是 base64 url 编码的,这与 base64 略有不同(替换 +
,\
与 -
,_
并删除尾随 =
)
使用此代码 DatatypeConverter.parseBase64Binary
解码 header 是错误的。需要使用:
java.util.Base64.getUrlDecoder().decode(string);
我查看了 JJWT 的代码并以正确的方式解码了 header。看DefaultJWTSParser第255行
String origValue = TextCodec.BASE64URL.decodeToString(base64UrlEncodedHeader);
可能您正在使用其他库?
我有一个由某些服务生成的 JWT 令牌,然后在我的 Java 应用程序上进行验证。
问题是由于 base64 解码错误,JJWT 库无法解析 JSON header。
Header 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 解码的特定环境吗?
您收到的 header 是 Base64 without output padding (note that there are 66 characters, which is not a multiple of 4). DatatypeConverter.parseBase64Binary
is specified to parse the XML Schema xsd:base64Binary
type, which requires output padding。显然它将末尾的 non-padded 字符视为无效字符并简单地忽略它们。
要么使用不同的解码器(Java 8 有 java.util.Base64
, Apache Commons.Codec has one, Guava has one too),要么自己填充输出(如果删除所有非 Base64 字符后的字符串长度不能被 4 整除,填充'=' 直到它是)。
JWT 的 header 和负载是 base64 url 编码的,这与 base64 略有不同(替换 +
,\
与 -
,_
并删除尾随 =
)
使用此代码 DatatypeConverter.parseBase64Binary
解码 header 是错误的。需要使用:
java.util.Base64.getUrlDecoder().decode(string);
我查看了 JJWT 的代码并以正确的方式解码了 header。看DefaultJWTSParser第255行
String origValue = TextCodec.BASE64URL.decodeToString(base64UrlEncodedHeader);
可能您正在使用其他库?