How to generate a self-signed certificate using only JDK supported classes?
<p>I have a program in Java which currently uses private JDK classes (<code>CertAndKeyGen</code> and <code>X500Name</code>) to generate self-signed X.509 certificates.
There are too many problems with this approach:</p>

<ul>
<li>the internal package(s) keep changing:

<ul>
<li>"sun.security.x509.CertAndKeyGen",          // Oracle/Sun/OpenJDK 6,7</li>
<li>"sun.security.tools.keytool.CertAndKeyGen", // Oracle/Sun/OpenJDK 8</li>
<li>"com.ibm.security.x509.CertAndKeyGen",      // IBM SDK 7</li>
<li>"com.ibm.security.tools.CertAndKeyGen"      // IBM SDK 8</li>
<li>Apparently a JDK 7 update (u111?) recently changed the package listed above</li>
</ul></li>
<li>Java 9 will hide these classes</li>
</ul>

<p>I would like to convert this code to use standard, supported JDK classes.</p>

<p>I have looked at using the ill-named <code>CertificateFactory.generateCertificate()</code> methods, but no luck: they cannot generate any certificate, they are just able to load an existing one.</p>

<p>&nbsp;</p>

<p>Does anybody know a standard JDK API that can generate a self-signed certificate?</p>

<p>&nbsp;</p>

<p>This is as far as I could go:</p>

<pre><code>KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048, SecureRandom.getInstance("SHA1WithRSA"));
KeyPair keyPair = generator.generateKeyPair();
PrivateKey privatekey = keyPair.getPrivate();

X500Principal principal = new X500Principal(dn);

CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
// How to generate the self-signed certificate from there?
// certFactory.generate(inputStream) // only able to load an existing certificate
</code></pre>

<p>&nbsp;</p>

<p>Note:</p>

<ul>
<li>We do not want to introduce a dependency on bouncy-castle if at all possible

<ul>
<li>I already know of <code>X509V3CertificateGenerator</code></li>
</ul></li>
<li>We do not want either to invoke <code>keytool</code> via a <code>ProcessBuilder</code> :)</li>
</ul>