我正在尝试使用别名和密码来检索X509证书,该证书已存储在KeyStore中。但是,在检索用于签署证书的私钥时,我经常会得到一个空指针异常。它有时有效,有时却无效。会有所帮助。谢谢!
在以下代码中,我尝试删除条件以检查它是否为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.
答案 0 :(得分:0)
需要明确的是-在正常情况下,您应该使用X509Certificate实例通过KeyManagerFactory中的KeyManager使用KeyStore与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();
}