JWT校验时RSA公钥字符串转PublicKey报invalid key format异常
问题根源
你现有代码的公钥转换逻辑存在错误:你拿到的去除首尾标记的RSA公钥字符串本身是Base64编码格式,不需要额外做Hex编码/解码操作,之前的Hex转码逻辑对原始公钥字符串做了无意义的转码,导致传入X509EncodedKeySpec的字节序列不符合规范,因此抛出java.security.InvalidKeyException: invalid key format异常。
正确实现方案(Java 8及以上版本,无额外依赖)
替换你的getPublicFederaKey方法为以下实现即可:
private PublicKey getPublicFederaKey() throws CustomException { try { // 移除公钥字符串中的换行、回车符和首尾空白 String keyTrimmed = publicKey.trim().replaceAll("[\n\r]", ""); // 直接对Base64格式的公钥字符串做解码 byte[] keyBytes = java.util.Base64.getDecoder().decode(keyTrimmed); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(keySpec); } catch (Exception e) { throw new CustomException(e.getMessage()); } }
低版本Java兼容实现(使用javax.xml.bind.DatatypeConverter)
如果你使用的Java版本低于8,可使用以下实现:
private PublicKey getPublicFederaKey() throws CustomException { try { String keyTrimmed = publicKey.trim().replaceAll("[\n\r]", ""); byte[] keyBytes = DatatypeConverter.parseBase64Binary(keyTrimmed); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(keySpec); } catch (Exception e) { throw new CustomException(e.getMessage()); } }
转换得到的PublicKey可以直接强转为RSAPublicKey,用在你原有的JWT校验逻辑中即可正常完成签名校验。
内容的提问来源于stack exchange,提问作者Swimcito
相关产品推荐
相关产品推荐

