Skip to content

Instantly share code, notes, and snippets.

@mikeapr4
Created February 12, 2016 15:48
Show Gist options
  • Save mikeapr4/3b2b5d05bc57640e77d0 to your computer and use it in GitHub Desktop.
Save mikeapr4/3b2b5d05bc57640e77d0 to your computer and use it in GitHub Desktop.
Convenient In-Memory Self-signed Certificate and Keystore creation for Java 8
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class CertificateUtils {
public static final String KEY_TYPE_RSA = "RSA";
public static final String SIG_ALG_SHA_RSA = "SHA1WithRSA";
public static final int KEY_SIZE = 1024;
public static final long CERT_VALIDITY = 365 * 24 * 3600L;
public static final String ALIAS_PRIVATE = "private";
public static final String ALIAS_CERT = "cert";
public static final String IN_MEMORY_PWD = "notReallyImportant"; // this would only ever be relevant if/when persisted.
private static final Logger LOGGER = LoggerFactory.getLogger(CertificateUtils.class);
/**
* @param certValues e.g. CN=Dave, OU=JavaSoft, O=Sun Microsystems, C=US
* @return
*/
public static KeyStore createSelfSigned(String certValues) {
try {
CertAndKeyGen keyGen = new CertAndKeyGen(KEY_TYPE_RSA, SIG_ALG_SHA_RSA);
keyGen.generate(KEY_SIZE);
KeyStore ks = emptyStore();
if (ks == null) {
return null;
}
X509Certificate certificate = keyGen.getSelfCertificate(new X500Name(certValues), CERT_VALIDITY);
ks.setCertificateEntry(ALIAS_CERT, certificate);
ks.setKeyEntry(ALIAS_PRIVATE, keyGen.getPrivateKey(), IN_MEMORY_PWD.toCharArray(), new Certificate[]{certificate});
return ks;
} catch (KeyStoreException | NoSuchAlgorithmException | NoSuchProviderException | CertificateException | SignatureException | InvalidKeyException | IOException e) {
LOGGER.error("Cannot create self signed certificate.", e);
}
return null;
}
public static KeyStore createSelfSignedForHost(String host) {
return createSelfSigned("CN=" + host);
}
public static KeyStore emptyStore() {
try {
KeyStore ks = KeyStore.getInstance("JKS");
// Loading creates the store, can't do anything with it until it's loaded
ks.load(null, IN_MEMORY_PWD.toCharArray());
return ks;
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e) {
LOGGER.error("Cannot create empty keystore.", e);
}
return null;
}
}
@eladchen
Copy link

@mikeapr4 Thank you!

@ylu999
Copy link

ylu999 commented Jan 15, 2021

@mikeapr4 Thank you for this.
Do you know this issue? I used basically the same thing for in memory KeyStore.
Thanks!

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[?:1.8.0_252] at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[?:1.8.0_252] at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[?:1.8.0_252] at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:445) ~[?:1.8.0_252] at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:317) ~[?:1.8.0_252] at sun.security.validator.Validator.validate(Validator.java:262) ~[?:1.8.0_252] at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:330) ~[?:1.8.0_252] at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:237) ~[?:1.8.0_252] at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132) ~[?:1.8.0_252] at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1670) ~[?:1.8.0_252] at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:226) ~[?:1.8.0_252] at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1082) ~[?:1.8.0_252] at sun.security.ssl.Handshaker.process_record(Handshaker.java:1010) ~[?:1.8.0_252] at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1079) ~[?:1.8.0_252] at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1388) ~[?:1.8.0_252] at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1416) ~[?:1.8.0_252] at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1400) ~[?:1.8.0_252] at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) ~[?:1.8.0_252] at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) ~[?:1.8.0_252] at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1570) ~[?:1.8.0_252] at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498) ~[?:1.8.0_252] at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:268) ~[?:1.8.0_252]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment