我想研究一个nssdb密钥库,以从可用别名中提取一些信息。在同一应用程序的其他部分,我使用BouncyCastleProvider
来处理其他一些安全事项。
下面的小代码显示了我如何加载和运行它,并且与openjdk-1.6.0一起正常工作。
现在,对于openjdk-1.7.0,它仅在我不使用BouncyCastleProvider
或在PKCS11提供程序之后添加了此提供程序的情况下才有效。
如果我在PKCS11之前添加BC,则一切似乎都正常(无例外),但是Keystore.aliases()
为我的nss容器返回了一个空列表。就像load()
无法正常工作一样。
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.util.Enumeration;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.security.cert.Certificate;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class TestNSS {
public static void main(String[] args) {
try {
Provider prov = new BouncyCastleProvider();
Security.addProvider(prov);
String config = "name = nssdb\n";
config += "nssSecmodDirectory = /nssdbpath\n";
InputStream stream = new ByteArrayInputStream(config.getBytes("UTF-8"));
Provider nss = new sun.security.pkcs11.SunPKCS11(stream);
stream.close();
Security.addProvider(nss);
KeyStore ks = KeyStore.getInstance("PKCS11", "SunPKCS11-nssdb");
ks.load((InputStream)null, "".toCharArray());
System.out.println("load is ok: SunPKCS11-nssdb");
for (Enumeration<String> e = ks.aliases(); e.hasMoreElements();) {
String alias = e.nextElement();
Certificate cert = ks.getCertificate(alias);
System.out.println(" . alias: "+alias+", "+cert.getType()+","+((X509Certificate)cert).getNotAfter());
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
任何想法都欢迎...
注意:/ nssdbpath包含使用certutil创建的nssdb结构。
最佳答案
我找到
-与openJDK6相比,java.security中的SunPKCS11实例是openjdk7的一项更改。
-通过nss.cfg而不是默认的“ nodb”模式加载nssdb似乎可以解决此问题,但这不是有效的解决方法,因为会引起诸如keytool错误的副作用...
此外,
-我仍然不知道BouncyCastleProvider为什么与SunPKCS11进行交互。
-看起来nssdb不是通过load()方法加载的,而是在SunPKCS11实例中加载的
-JVM中只能加载一个具有单个nssdb的SunPKCS11实例
=> SunPKCS11不是读取nssdb数据的好方法:我将通过外部(非Java)代码作为解决方法。
无论如何,如果有人有其他解决方案,我仍然会对阅读感兴趣。