KeyStore [ java.lang.IllegalArgumentException: missing provider ] [BouncyCastle]
源码展示
KeyStore ks = KeyStore.getInstance("PKCS12", getProvider());
FileInputStream fis = new FileInputStream(pfxPath);
// If the keystore password is empty(""), then we have to set
// to null, otherwise it won't work!!!
char[] nPassword = null;
if ((pfxPassword == null) || pfxPassword.trim().equals("")) {
nPassword = null;
} else {
nPassword = pfxPassword.toCharArray();
}
ks.load(fis, nPassword);
fis.close();
KeyStore 是Java提供的一个类,用于存储私钥和公钥证书;在获取KeyStore实例时出现异常错误
错误信息
错误信息为:IllegalArgumentException:缺少提供程序
BouncyCastle 注册后,提示内容不存在
问题分析
1.错误原因
报错位置源码如下:
public static KeyStore getInstance(String type, Provider provider)
throws KeyStoreException
{
if (provider == null)
throw new IllegalArgumentException("missing provider");
try {
Object[] objs = Security.getImpl(type, "KeyStore", provider);
return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
} catch (NoSuchAlgorithmException nsae) {
throw new KeyStoreException(type + " not found", nsae);
}
}
根据以上代码可以看出,异常原因为: Provider 为 null 出现错误;
而获取 Provider 实例 使用方法如下:
private static Provider getProvider() {
return Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
}
获取 Provider实例 从Java的Security类中获取一个安全提供者实例,该提供者实现了BouncyCastle加密库的功能;
BouncyCastle 注册后,内容不存在;
2.错误排查
BouncyCastle版本验证
使用代码查看调用版本,判断BouncyCastle 是否存在;是否与引入版本一致
System.out.println( "version=" + Security.getProvider(BouncyCastleProvider.PROVIDER_NAME).getVersion());
引入版本不一致
如果引入版本与查看版本不一致的话,对Provider移除;
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
添加Provider实例
a.在执行版本验证时,依旧为错误信息;版本验证代码未执行;
b.引入版本不一致,移除后需要重新添加
Security.addProvider(new BouncyCastleProvider());
引入后重新验证版本
private static Provider getProvider() {
Security.addProvider(new BouncyCastleProvider());
System.out.println( "version=" + Security.getProvider(BouncyCastleProvider.PROVIDER_NAME).getVersion());
return Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
}
如果版本依旧与引入版本不一致,需要对引入jar进行处理,查看是否存在多版本问题;
3.处理结果
第一次执行版本验证时,依旧出现错误,版本代码并未执行,因此重新添加 Provider实例/重新引入;
重新引入后,输出内容与引入版本一致,调用方法也未出现 IllegalArgumentException
对 getProvider() 方法进行优化
private static Provider getProvider() {
Security.addProvider(new BouncyCastleProvider());
//System.out.println( "version=" + Security.getProvider(BouncyCastleProvider.PROVIDER_NAME).getVersion());
return Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
}
引入BouncyCastle 版本为 1.68;输出版本一致