Reputation: 157
I want to generate an X509 certificate for a private key stored in the Google Cloud HSM.
Using Java Key tool and a local Java "keystore" i would do something like this:
keytool -exportcert -alias sign1 -keystore signkeystore -storetype jks -storepass password -file sign1.certificate
See http://tutorials.jenkov.com/java-cryptography/keytool.html
Using OpenSSL i would do something like this:
openssl genrsa -out private.key 1024
openssl req -new -x509 -key private.key -out publickey.cer -days 365
openssl pkcs12 -export -out public_privatekey.pfx -inkey private.key -in publickey.cer
See X.509: Private / Public Key
It would seem, generating a certificate needs access to the "private key", in some fashion, either directly like OpenSSL or indirectly like keytool using the private keystore.
Gcloud documentation seems to use OpenSSL for generating the private key. https://cloud.google.com/load-balancing/docs/ssl-certificates
How do i get a X509 certificate for a private key in Google Cloud HSM. Has anyone done this before ?
Regards Suchak
Upvotes: 2
Views: 2272
Reputation: 157
I had a look at this thread Creating an X509 Certificate in Java without BouncyCastle?.
Then I did the following two create a GCloud X509 Certificate
/**
* Create a self-signed X.509 based on a public key
* @param googlePublicKey the Public key downloaded from Google Cloud HSM
* @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB"
* @param days how many days from now the Example is valid for
* @param algorithm the signing algorithm, eg "SHA1withRSA"
*/
public static X509Certificate generateRSACertificate(String googlePublicKey, String dn, int days, String algorithm)
throws GeneralSecurityException, IOException {
byte[] derKey = Base64.decodeBase64(googlePublicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(derKey);
PublicKey rsaKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privkey = keyPair.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);
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(rsaKey));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_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(privkey, algorithm);
// Update the algorith, 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;
}
Imports used were
import org.apache.commons.codec.binary.Base64;
import sun.security.x509.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Collection;
import java.util.Date;
Upvotes: 1