最近一个项目要用一个RSA公钥对签名过的文件进行验证。公钥如下:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtohucPE/IWn+S+nFbMvQ
L8cGcxltm+AJsSQS1W+o1uMALERPnQt2Xas5zVxiFUCx9IBatkR+l/3yVSFwCfEd
mFmIzkR2Y6sgL3DWfZ3ff7KK6rbL5hYw10n+AGp+/JfDmlWx2ANQmTG0djX8MsQo
Nb6OgHko3pO8w6TJ2VzFMKPGOpIavIN8Q7euSZiuzsQl/IP0acW9c601lQxP0cnA
1KbtpDlm37cOgVIpc51NaQU660WpR6UitNcXM+rrPCdOMKBS8LwXKT6p8SDt5ojD
1aJA6sNr1cHRoL+UI+bCX+WwRYdgv+dZM0+4+RNNejGJ+ecFP6NAigXrIDR3Caih
GwIDAQAB
-----END PUBLIC KEY-----
于是找了公钥加载的java函数方法,如下:
/**
* 从字符串中加载公钥
*
* @param publicKeyStr
* 公钥数据字符串
* @throws Exception
* 加载公钥时产生的异常
*/
public static void loadPublicKey(String publicKeyStr) throws Exception {
try {
BASE64Decoder base64Decoder = new BASE64Decoder();
byte[] buffer = base64Decoder.decodeBuffer(publicKeyStr);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new Exception("无此算法");
} catch (InvalidKeySpecException e) {
throw new Exception("公钥非法");
} catch (IOException e) {
throw new Exception("公钥数据内容读取错误");
} catch (NullPointerException e) {
throw new Exception("公钥数据为空");
}
}
在加载的时候用了如下方法获取公钥内容:
private static String readFileToString(String filePath) {
BufferedReader reader = null;
StringBuilder fileData = null;
try {
fileData = new StringBuilder(1000);
reader = new BufferedReader(new FileReader(filePath));
char[] buf = new char[1024];
int numRead = 0;
while ((numRead = reader.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != reader)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return fileData.toString();
}
然后调用loadPublicKey函数对上面的获取的字符串进行解析成RSAPublicKey,于是报了InvalidKeySpecException异常。
后面发现是由于loadPublicKey只需要解析的字符串不能有回车换行和空格,只要传入公钥内容即可。于是把公钥中的
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtohucPE/IWn+S+nFbMvQ
L8cGcxltm+AJsSQS1W+o1uMALERPnQt2Xas5zVxiFUCx9IBatkR+l/3yVSFwCfEd
mFmIzkR2Y6sgL3DWfZ3ff7KK6rbL5hYw10n+AGp+/JfDmlWx2ANQmTG0djX8MsQo
Nb6OgHko3pO8w6TJ2VzFMKPGOpIavIN8Q7euSZiuzsQl/IP0acW9c601lQxP0cnA
1KbtpDlm37cOgVIpc51NaQU660WpR6UitNcXM+rrPCdOMKBS8LwXKT6p8SDt5ojD
1aJA6sNr1cHRoL+UI+bCX+WwRYdgv+dZM0+4+RNNejGJ+ecFP6NAigXrIDR3Caih
GwIDAQAB 整合成一个不含回车空格的字符串即可。