void setKeyEntry(String alias, byte[] key, Certificate[] chain)
You'll need at least one Certificate object to accompany the private key. You may be tempted (or already attempted) to 'skip' producing the Certificate object using this method:
void setEntry(String alias, KeyStore.Entry entry, KeyStore.ProtectionParameter protParam)
But you'll discover that a java.security.KeyStore.PrivateKeyEntry object needs a Certificate[] object passed in as well.
This led to the code below to generate the required Certificate object, just enough to fulfil the requirements to save the private key:
Of course, if you have the aid of an IDE, the BouncyCastle methods used are deprecated (using v1.47). So, being a good Java coder, I've followed the advice in the BC javadocs and replaced the deprecated methods with the following equivalent code:
May your sanity be in check as you navigate through the waters of Java security.
This led to the code below to generate the required Certificate object, just enough to fulfil the requirements to save the private key:
@Deprecated
private Certificate[] generateCertificateOld(KeyPair keyPair) throws Exception {
Date startDate = new Date(System.currentTimeMillis());
Date expiryDate = DateUtils.parseDate("01/01/2100", new String[] { "dd/MM/yyyy" });
BigInteger serialNumber = new BigInteger(String.valueOf(System.currentTimeMillis()));
X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
X500Principal dnName = new X500Principal("CN=Storage Certificate");
certGen.setSerialNumber(serialNumber);
certGen.setIssuerDN(dnName);
certGen.setNotBefore(startDate);
certGen.setNotAfter(expiryDate);
certGen.setSubjectDN(dnName); // note: same as issuer
certGen.setPublicKey(keyPair.getPublic());
certGen.setSignatureAlgorithm("SHA256withRSA");
return new Certificate[] {certGen.generate(keyPair.getPrivate())};
}
Of course, if you have the aid of an IDE, the BouncyCastle methods used are deprecated (using v1.47). So, being a good Java coder, I've followed the advice in the BC javadocs and replaced the deprecated methods with the following equivalent code:
private Certificate[] generateCertificate(KeyPair keyPair) throws Exception {
X509v1CertificateBuilder certGen = new JcaX509v1CertificateBuilder(
new X500Name("CN=Storage Certificate"),
BigInteger.valueOf(System.currentTimeMillis()),
new Date(System.currentTimeMillis()),
DateUtils.parseDate("01/01/2100", new String[] { "dd/MM/yyyy" }),
new X500Name("CN=Storage Certificate"),
keyPair.getPublic());
JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256withRSA");
ContentSigner contentSigner = contentSignerBuilder.build(keyPair.getPrivate());
X509CertificateHolder certHolder = certGen.build(contentSigner);
JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter();
Certificate cert = certConverter.getCertificate(certHolder);
Certificate[] certs = { cert };
return certs;
}
May your sanity be in check as you navigate through the waters of Java security.