You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 05:03:40