使用 com.google.common.io.BaseEncoding 解码 Base64 -> 解码异常:无法识别的字符:-



总体目标

我想用com.google.common.io.BaseEncoding库替换com.google.api.client.util.Base64库,因为它已被弃用(我正在使用Java 11)。

我使用这些库来验证rsa签名的jwt。为了创建公钥,我使用证书的n和e值的字符串表示形式,并将其转换为BigInteger。

<标题>

我的解决方案总是抛出这个异常:com.google.common.io.BaseEncoding$DecodingException: Unrecognized character: -

我想解码的字符串中有-字符,但我不知道如何使用BaseEncoding包来解决这个问题。

有人遇到这个问题可以帮助我吗?

<标题>代码以下是com.google.api.client.util.Base64解码的代码:
package com.example;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.Calendar;
import com.auth0.jwk.InvalidPublicKeyException;
import com.auth0.jwk.JwkException;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.api.client.util.Base64;

public final class App {
public final static String PUBLIC_KEY_ALGORITHM = "RSA";
/**
* 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);
byte[] decodedPubN = Base64.decodeBase64(PUB_N);
byte[] decodedPubE = Base64.decodeBase64(PUB_E);
BigInteger modulus = new BigInteger(1, decodedPubN);
BigInteger exponent = new BigInteger(1, decodedPubE);
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);
}
}
/**
* 
* 
* @param args The arguments of the program.
* @throws JwkException
*/
public static void main(String[] args) throws JwkException {
DecodedJWT jwt = JWT.decode(TOKEN);
PublicKey publicKey = getPublicKey();
Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) publicKey, null);
algorithm.verify(jwt);

if (jwt.getExpiresAt().before(Calendar.getInstance().getTime())) {
throw new RuntimeException("Expired token!");
}
}
}

我用com.google.common.io.BaseEncoding库重构了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);
BigInteger modulus = new BigInteger(1, BaseEncoding.base64().decode(pubN));
BigInteger exponent = new BigInteger(1, BaseEncoding.base64().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);
}
}

就像前面提到的注释一样,JWT使用Base64Url编码。我只需要把BaseEncoding.base64().decode(pubN)改成BaseEncoding.base64Url().decode(pubN)

最新更新