Reputation: 11
I generate a certificate signing request (CSR) by getting keypair from CloudHsmProvider's Keystore and use bouncycastle to generate csr, but I getting error java.lang.UnsupportedOperationException: getPrivateExponent is not supported by CloudHsmRsaPrivateCrtKey. On the other hand if I create the keypair (not save to the keystore) and then create the csr too, there is no such error and I still get the desired csr file. So is my problem caused by error when saving keypair to keystore?
Create CSR
public static void main(String[] args) {
try {
try {
if (Security.getProvider(CloudHsmProvider.PROVIDER_NAME) == null) {
Security.addProvider(new CloudHsmProvider());
}
} catch (IOException ex) {
System.out.println(ex);
return;
}
String keystoreFile = "abc.p12";
String password = "123456";
String label = "tuan14";
final String privateLabel = label + ":Private";
final KeyStore keyStore = KeyStore.getInstance(CloudHsmProvider.CLOUDHSM_KEYSTORE_TYPE);
try {
final FileInputStream instream = new FileInputStream(keystoreFile);
keyStore.load(instream, password.toCharArray());
} catch (final FileNotFoundException ex) {
System.err.println("Keystore not found, loading an empty store");
keyStore.load(null, null);
}
final PasswordProtection passwordProtection = new PasswordProtection(password.toCharArray());
System.out.println("Searching for example key pair and certificate...");
final PrivateKeyEntry keyEntry =
(PrivateKeyEntry) keyStore.getEntry(privateLabel, passwordProtection);
final String name = keyEntry.getCertificate().toString();
System.out.printf("Found private key %s with certificate %s%n", label, name);
PublicKey publicKey = keyEntry.getCertificate().getPublicKey();
PrivateKey privateKey = keyEntry.getPrivateKey();
X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE);
x500NameBld.addRDN(BCStyle.CN, "ABC");
x500NameBld.addRDN(BCStyle.C, "Viet Nam");
x500NameBld.addRDN(BCStyle.ST, "Hà nội");
x500NameBld.addRDN(BCStyle.L, "Cầu Giấy");
x500NameBld.addRDN(BCStyle.O, "ABC");
x500NameBld.addRDN(BCStyle.OU, "ABC");
x500NameBld.addRDN(BCStyle.UID, "1427732196");
x500NameBld.addRDN(BCStyle.UID, "1427732189");
x500NameBld.addRDN(BCStyle.TELEPHONE_NUMBER, "0339028712");
x500NameBld.addRDN(BCStyle.EmailAddress, "[email protected]");
x500NameBld.addRDN(BCStyle.STREET, "abc");
X500Name subject = x500NameBld.build();
PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
subject, publicKey);
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");
ContentSigner signer = csBuilder.build((PrivateKey) privateKey);
PKCS10CertificationRequest csr = p10Builder.build(signer);
PemObject pemObject = new PemObject("CERTIFICATE REQUEST", csr.getEncoded());
StringWriter strWriter;
try (JcaPEMWriter pemWriter = new JcaPEMWriter(strWriter = new StringWriter())) {
pemWriter.writeObject(pemObject);
}
writeToFile(strWriter.toString().getBytes(), "demo.pem");
} catch (Throwable thr) {
thr.printStackTrace();
System.out.println("HSM Exception printStackTrace():");
}
}
Store Keypair
private static X509Certificate generateCertificate(String dn, String issuer, KeyPair pair, int days,
String algorithm) throws GeneralSecurityException, IOException {
PrivateKey privkey = pair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
Date to = new Date(from.getTime() + days * 86400000l);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger sn = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);
X500Name issuerName = new X500Name(issuer);
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
if ("1.8".equals(System.getProperty("java.specification.version"))) {
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
info.set(X509CertInfo.SUBJECT, owner);
info.set(X509CertInfo.ISSUER, issuerName);
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
}
X509CertImpl cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
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 static void main(String[] args) {
try {
try {
if (Security.getProvider(CloudHsmProvider.PROVIDER_NAME) == null) {
Security.addProvider(new CloudHsmProvider());
}
} catch (IOException ex) {
System.out.println(ex);
return;
}
String password = "123456";
String label = "tuan14";
String keystoreFile = "./abc.p12";
String privateLabel = label+":Private";
final PasswordProtection passwordProtection =
new PasswordProtection(password.toCharArray());
KeyStore keyStore = KeyStore.getInstance(CloudHsmProvider.CLOUDHSM_KEYSTORE_TYPE);
keyStore.load(null, password.toCharArray());
final KeyAttributesMap requiredPublicKeyAttributes =
new KeyAttributesMapBuilder().put(KeyAttribute.VERIFY, true).build();
final KeyAttributesMap requiredPrivateKeyAttributes =
new KeyAttributesMapBuilder().put(KeyAttribute.SIGN, true).build();
final KeyPair keyPair =
AsymmetricKeys.generateRSAKeyPair(
2048, label, requiredPublicKeyAttributes, requiredPrivateKeyAttributes);
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
System.out.println("Keypair info: ");
System.out.println("Private key: " + privateKey.toString());
System.out.println("Public key: " + publicKey);
System.out.println("Algo PrivateKey: " + privateKey.getAlgorithm());
X509Certificate rootCertificate = generateCertificate(
"CN="+label,
"CN="+label,
keyPair,
30,
"SHA256WithRSA");
//Create Chain
X509Certificate[] chain = new X509Certificate[1];
chain[0] = rootCertificate;
final PrivateKeyEntry entry = new PrivateKeyEntry(keyPair.getPrivate(), chain);
keyStore.setEntry(privateLabel, entry, passwordProtection);
final FileOutputStream outstream = new FileOutputStream(keystoreFile);
keyStore.store(outstream, password.toCharArray());
outstream.close();
} catch (Throwable thr) {
thr.printStackTrace();
System.out.println("HSM Exception printStackTrace():");
}
}
public static KeyPair generateRSAKeyPair(
int keySizeInBits,
String label,
KeyAttributesMap additionalPublicKeyAttributes,
KeyAttributesMap additionalPrivateKeyAttributes)
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException,
NoSuchProviderException, AddAttributeException {
KeyPairGenerator keyPairGen =
KeyPairGenerator.getInstance("RSA", CloudHsmProvider.PROVIDER_NAME);
final KeyAttributesMap publicKeyAttrsMap = new KeyAttributesMap();
publicKeyAttrsMap.putAll(additionalPublicKeyAttributes);
publicKeyAttrsMap.put(KeyAttribute.LABEL, label + ":Public");
publicKeyAttrsMap.put(KeyAttribute.MODULUS_BITS, keySizeInBits);
publicKeyAttrsMap.put(KeyAttribute.PUBLIC_EXPONENT, new BigInteger("65537").toByteArray());
final KeyAttributesMap privateKeyAttrsMap = new KeyAttributesMap();
privateKeyAttrsMap.putAll(additionalPrivateKeyAttributes);
privateKeyAttrsMap.put(KeyAttribute.LABEL, label + ":Private");
KeyPairAttributesMap keyPairSpec =
new KeyPairAttributesMapBuilder()
.withPublic(publicKeyAttrsMap)
.withPrivate(privateKeyAttrsMap)
.build();
keyPairGen.initialize(keyPairSpec);
return keyPairGen.generateKeyPair();
}
Upvotes: 1
Views: 1178