This post demonstrates how to generate a self-signed certificate with Java and BouncyCastle. There are numerous posts online about how to generate a self-signed certificate using the Java Keytool, so I won’t cover that here. Instead, you may be looking for how to generate a self-signed certificate programmatically using Java. I’ve written an example using the BouncyCastle library (https://www.bouncycastle.org/).
Before we begin with the Java and BouncyCastle examples, let’s dive into using OpenSSL to more quickly demonstrate what we will be doing.
Using OpenSSL to generate a self-signed certificate
To generate a new self signed certificate and private key with openssl, run the following command:
openssl req -nodes -newkey rsa:2048 -keyout example.key -out example.crt -x509 -days 365

Where -nodes
writes the private key decrypted in plain text, -newkey rsa:2048
specifies a bit size of 2048, -keyout example.key
is the file where the private key is stored, -out example.crt
is the self signed certificate, and -x509 -days 365
specifies the generated X509 certificate will have a validity period of 365 days.
If you have an existing private key and CSR, you can run the following openssl command to create a self signed certificate:
openssl x509 -req -in example.csr -signkey example.key -out example.crt -days 365
Self signed certificates can be used in a trusted environment where public trust is not required. For example, internal systems may use self signed certificates where the clients know they can trust the certificate and do not need to trust the CA certificates in their OS or application trust stores.
Self signed certificates may also be used as a CA certificate to sign and issue end entity or leaf certificates. To dive further into using openssl as a CA, head over to our article on using openssl as a CA.
Using Java and BouncyCastle
Steps to create the self-signed certificate with Java and BouncyCastle:
- Create a validity period of not before and not after based on the current Instant and given amount of days.
- Use the BouncyCastle JcaContentSignerBuilder with the given PrivateKey to sign the certificate to be built.
- The X500Name should be the common name (Fully Qualified Domain Name (FQDN) of the server or any name if a client cert).
- Use the BouncyCastle X509v3CertificateBuilder to build the certificate.
- Add subject key id, authority key id, and basic constraint extensions to the builder.
- Return the self-signed certificate.
public static X509Certificate generate(final KeyPair keyPair,
final String hashAlgorithm,
final String cn,
final int days)
throws OperatorCreationException, CertificateException, CertIOException
{
final Instant now = Instant.now();
final Date notBefore = Date.from(now);
final Date notAfter = Date.from(now.plus(Duration.ofDays(days)));
final ContentSigner contentSigner = new JcaContentSignerBuilder(hashAlgorithm).build(keyPair.getPrivate());
final X500Name x500Name = new X500Name("CN=" + cn);
final X509v3CertificateBuilder certificateBuilder =
new JcaX509v3CertificateBuilder(x500Name,
BigInteger.valueOf(now.toEpochMilli()),
notBefore,
notAfter,
x500Name,
keyPair.getPublic())
.addExtension(Extension.subjectKeyIdentifier, false, createSubjectKeyId(keyPair.getPublic()))
.addExtension(Extension.authorityKeyIdentifier, false, createAuthorityKeyId(keyPair.getPublic()))
.addExtension(Extension.basicConstraints, true, new BasicConstraints(true));
return new JcaX509CertificateConverter()
.setProvider(new BouncyCastleProvider()).getCertificate(certificateBuilder.build(contentSigner));
}
The complete working program is in my github repo: https://github.com/misterpki/selfsignedcert
There exist other ways to programmatically do this in both Java and other languages. Please leave comments, ask questions, and leave feedback if interested in learning other ways to programmatically create a self-signed certificate.
Leave a Reply