我有一个使用SunPKCS11和网络连接的HSM在tomcat中运行的PDF签名应用程序。提供程序存储在应用程序上下文中,并在需要时从那里检索。一切正常,除了在tomcat和HSM之间的连接丢失(例如,在网络中断之后)之后,PKCS11提供程序无法恢复,并且tomcat需要重新启动。我正在寻找一种方法来在失败(我发现并采取行动)之后重新初始化提供程序。
public Provider loadProvider(Boolean forceReInit) {
ServletContext ctx = getServletContext();
Provider provider = null;
Provider cached = (Provider)ctx.getAttribute("cachedProvider");
if(cached == null || forceReInit) {
for(Provider p: Security.getProviders()) {
if(p.getName().contains("PKCS11")) {
Security.removeProvider(p.getName());
p.clear();
}
}
String configPath = "/path/to/pkcs11.cfg";
provider = new SunPKCS11(new FileInputStream(configPath)); // Exception here
Security.addProvider(provider);
ctx.setAttribute("cachedProvider", provider);
} else {
provider = cached;
}
return provider;
}
像这样使用:
public class Signer {
...
for(int i=0; i<2; i++) {
Boolean forceReInit = (i>0);
try {
Provider p = loadProvider(forceReInit);
return signDocumentWithProvider(p);
} catch(Exception ex) {
if(forceReInit) {
// bail out after second failure
throw(ex);
}
continue;
}
}
}
尝试加载新的SunPKCS11时,即使我已经卸载了它,我总是得到java.security.ProviderException
。
根据导致重新加载提供程序的错误/中断的类型,异常有所不同,但此后保持不变(以下是一个示例)。
Caused by: java.security.ProviderException: Initialization failed
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:376)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:107)
at my.package.loadProvider(Signer.java:102)
... 28 more
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_GENERAL_ERROR
at sun.security.pkcs11.wrapper.PKCS11.C_GetTokenInfo(Native Method)
at sun.security.pkcs11.Token.<init>(Token.java:135)
at sun.security.pkcs11.SunPKCS11.initToken(SunPKCS11.java:858)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:367)
... 30 more
有人知道在驱动程序出现故障后如何重新初始化SunPKCS11提供程序吗?