Guava BaseEncoding解码Base64报Unrecognized character:-异常
问题根因
报错的核心原因是Base64编码变体不匹配:
- JWK规范中RSA公钥的模数
n、公钥指数e均采用Base64URL编码,该变体为了适配URL传输场景,会将标准Base64中的+替换为-、/替换为_,且通常省略末尾用于对齐长度的=填充符。 - 原依赖
com.google.api.client.util.Base64的decodeBase64方法内置了多格式兼容逻辑,可自动识别Base64URL的特殊字符、补全缺失填充,因此可以正常解码。 - 重构时使用的
BaseEncoding.base64()实例仅支持标准Base64字符集(A-Za-z0-9+/),遇到-这类Base64URL专属字符时就会抛出DecodingException: Unrecognized character: -异常。
修复方案
使用Guava BaseEncoding提供的Base64URL专用解码实例,同时配置忽略缺失的填充符,即可和旧库的解码行为完全对齐,无需手动替换字符或补全填充。
修正后的getPublicKey方法代码如下:
/** * Returns a {@link PublicKey} if the {@code 'alg'} is {@code 'RSA'} * * @return a public key * @throws InvalidPublicKeyException if the key cannot be built or the key type is not RSA */ public static PublicKey getPublicKey() throws InvalidPublicKeyException { try { KeyFactory kf = KeyFactory.getInstance(PUBLIC_KEY_ALGORITHM); // 替换为base64Url实例,配置忽略缺失的填充符 BaseEncoding base64Decoder = BaseEncoding.base64Url().ignorePadding(); BigInteger modulus = new BigInteger(1, base64Decoder.decode(pubN)); BigInteger exponent = new BigInteger(1, base64Decoder.decode(pubE)); return kf.generatePublic(new RSAPublicKeySpec(modulus, exponent)); } catch (InvalidKeySpecException e) { throw new InvalidPublicKeyException("Invalid public key", e); } catch (NoSuchAlgorithmException e) { throw new InvalidPublicKeyException("Invalid algorithm to generate key", e); } }
注意事项
- 不要手动写字符串替换逻辑把
-换成+、_换成/再用标准Base64解码,容易漏处理填充符问题,用官方提供的Base64URL实例更稳妥。 - 该配置下的解码结果和旧库
com.google.api.client.util.Base64.decodeBase64()的返回结果完全一致,不会影响后续RSA公钥生成、JWT验签的逻辑正确性。
内容的提问来源于stack exchange,提问作者snice
相关产品推荐
相关产品推荐

