java - 从密钥库中检索 X509 证书时出错
问题描述
我正在尝试使用别名和密码检索已存储在 KeyStore 中的 X509Certificate。但是在检索用于签署证书的私钥时,我经常会遇到空指针异常。它有时有效,有时无效。会有一点帮助。谢谢!
在下面的代码中,我尝试删除条件以检查它是否是 PrivateKey 实例。它不起作用。
public X509Certificate generateCertificate(String userId, char[] password, KeyPair newKeyPair, String algorithm) throws Exception
{
KeyPair groupManagerKeyPair = LoadKeyPair(gmPath, "EC");
PrivateKey gmPrivateKey = groupManagerKeyPair.getPrivate();
String dn = "CN="+userId;
//char[] password = user.getPassword().toCharArray();
String alias = userId;
X509CertInfo info = new X509CertInfo();
Date from = new Date();
Date to = new Date(from.getTime() + 365 * 86400000l);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger sn = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
info.set(X509CertInfo.SUBJECT, owner);
info.set(X509CertInfo.ISSUER, owner);
info.set(X509CertInfo.KEY, new CertificateX509Key((PublicKey) newKeyPair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V1));
AlgorithmId algo = new AlgorithmId(AlgorithmId.sha256WithECDSA_oid);
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
// Sign the cert to identify the algorithm that's used.
X509CertImpl cert = new X509CertImpl(info);
cert.sign(gmPrivateKey, algorithm);
X509Certificate[] certificateChain = new X509Certificate[1];
certificateChain[0] = cert;
System.out.println("cert::"+cert);
//save certificate into keyStore
saveCertificateInKeyStore(alias, password, gmPrivateKey, certificateChain);
// Update the algorithm, and resign.
/*algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG);
info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);*/
return cert;
}
public void storeKeyAndCertificateChain(String alias, char[] password, Key key, X509Certificate[] chain) throws Exception{
String keystore = "D:\\testkeys.jks";
KeyStore keyStore=KeyStore.getInstance("jks");
keyStore.load(null,null);
keyStore.setKeyEntry(alias, key, password, chain);
keyStore.store(new FileOutputStream(keystore),password);
}
public X509Certificate loadAndDisplayChain(String alias,char[] password) throws Exception{
//Reload the keystore
String keystore = "D:\\testkeys.jks";
KeyStore keyStore=KeyStore.getInstance("jks");
keyStore.load(new FileInputStream(keystore),password);
Key key=keyStore.getKey(alias, password);
X509Certificate x509Certificate = null;
if(key instanceof PrivateKey){
System.out.println("Get private key : ");
System.out.println(key.toString());
Certificate[] certs=keyStore.getCertificateChain(alias);
System.out.println("Certificate chain length : "+certs.length);
for(Certificate cert:certs){
System.out.println(cert.toString());
if(certs.length == 1)
x509Certificate = (X509Certificate) cert;
}
}else{
System.out.println("Key is not private key");
}
return x509Certificate;
}
I expect that it should load the certificate using the parameters.. alias and password.
解决方案
只是要清楚一点-在正常情况下,您应该使用 X509Certificate 实例使用 KeyManagerFactory 中的 KeyManager 使用 KeyStore 来初始化 SSLContext 等等......
但是可以说你需要检查一些东西。您需要做的只是确保您的 KeyStore 已初始化:
private String keystoreType = "JKS_or_PKCS12";
private String keystoreName = "path_to_keystore";
private String keystorePassword = "your_password";
@Bean
public KeyStore keyStore() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
KeyStore keyStore = KeyStore.getInstance(keystoreType);
try (InputStream keyStoreStream = new FileInputStream(keystoreName)) {
keyStore.load(keyStoreStream, keystorePassword.toCharArray());
}
return keyStore;
}
并获取您的 X509Certificate 实例:
public X509Certificate[] x509Certificates(KeyStore keyStore) throws KeyStoreException {
Enumeration<String> aliases = keyStore.aliases();
List<X509Certificate> trustedIssuers = new ArrayList<>();
while (aliases.hasMoreElements()) {
trustedIssuers.add((X509Certificate) keyStore.getCertificate(aliases.nextElement()));
}
return trustedIssuers.toArray(new X509Certificate[0]);
}
要获取您的私钥:
public PrivateKey getPrivateKey(KeyStore keyStore, String keystorePassword, String alias)
throws UnrecoverableEntryException, NoSuchAlgorithmException, KeyStoreException {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,
new KeyStore.PasswordProtection(keystorePassword.toCharArray()));
return privateKeyEntry.getPrivateKey();
}
推荐阅读
- java - 如何将任务重新分配到 Hadoop?
- android - HintRequest 显示 3 sim 号码
- reactjs - React - 来自 PHP 的登录错误未显示
- hostapd - 当不断改变hostapd的模式(ap 2 sta)时,netifd的进程堆在上升
- lightbox2 - 为什么 showImageNumberLabel 选项不影响灯箱默认设置?
- cmake - Visual Studio 中的私有和公共头文件(基于 CMake 的项目)
- c++ - 使用矢量析构函数时出现奇怪的错误
- machine-learning - 如何在两侧归零并将序列编码为keras中的一个热点?
- java - TestNG 未找到任何测试。什么都没有运行
- docker - 访问其中一个容器内的 docker shell