jwt使用rsa加密时报错(main方法测试始终正确,一使用web运行就报错)
错误信息
java.security.InvalidKeyException: IOException: DerInputStream.getLength(): lengthTag=13, too big.
原因:多线程引起的并发问题(更具体的原因不清楚)。
解决:使用synchronized (或者Lock,我懒得用Lock了)
/**
* 从文件中获取公钥
*
* @param publicKeyFilePath
* 文件路径
* @return
*/
public synchronized static PublicKey getPublicKey(String publicKeyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
return getPublicKey(new FileInputStream(publicKeyFilePath));
}
/**
* 从文件中获取公钥
*
* @param publicKeyFilePath
* classpath中的文件相对路径(只有文件名都行,ClassLoader.getResourceAsStream会自行搜索)
* @return
*/
public synchronized static PublicKey getPublicKeyClasspath(String publicKeyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
return getPublicKey(RsaKeyUtil.class.getClassLoader().getResourceAsStream(publicKeyFilePath));
}
/**
* 从字节输入流中获取公钥
*
* @param publicKeyInput
* @return
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public synchronized static PublicKey getPublicKey(InputStream publicKeyInput) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
try (InputStream input = publicKeyInput; DataInputStream dis = new DataInputStream(input)) {
byte[] keyBytes = new byte[input.available()];
dis.readFully(keyBytes);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
}
public synchronized static PublicKey getPublicKey64(String publicKeyFilePath) throws Exception {
return getPublicKey64(new FileInputStream(publicKeyFilePath));
}
public synchronized static PublicKey getPublicKey64Classpath(String publicKeyFilePath) throws Exception {
return getPublicKey64(RsaKeyUtil.class.getClassLoader().getResourceAsStream(publicKeyFilePath));
}
public synchronized static PublicKey getPublicKey64(InputStream publicKeyInput) throws Exception {
try (InputStream input = publicKeyInput) {
String key64 = FileUtil.readAllString(input);
byte[] keyByte = Base64Util.decodeBase64(key64);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyByte);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
}