alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (SelfSignedCertificate.java)

This example Java source code file (SelfSignedCertificate.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

begin, certificate-----\n, certificateexception, date, default_not_after, default_not_before, failed, file, ioexception, outputstream, privatekey, security, selfsignedcertificate, string, util, x509certificate

The SelfSignedCertificate.java Java example source code

/*
 * Copyright 2014 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package io.netty.handler.ssl.util;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.base64.Base64;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;

/**
 * Generates a temporary self-signed certificate for testing purposes.
 * <p>
 * <strong>NOTE:
 * Never use the certificate and private key generated by this class in production.
 * It is purely for testing purposes, and thus it is very insecure.
 * It even uses an insecure pseudo-random generator for faster generation internally.
 * </p>

* A X.509 certificate file and a RSA private key file are generated in a system's temporary directory using * {@link java.io.File#createTempFile(String, String)}, and they are deleted when the JVM exits using * {@link java.io.File#deleteOnExit()}. * </p>

* At first, this method tries to use OpenJDK's X.509 implementation (the {@code sun.security.x509} package). * If it fails, it tries to use <a href="http://www.bouncycastle.org/">Bouncy Castle as a fallback. * </p> */ public final class SelfSignedCertificate { private static final InternalLogger logger = InternalLoggerFactory.getInstance(SelfSignedCertificate.class); /** Current time minus 1 year, just in case software clock goes back due to time synchronization */ private static final Date DEFAULT_NOT_BEFORE = new Date(SystemPropertyUtil.getLong( "io.netty.selfSignedCertificate.defaultNotBefore", System.currentTimeMillis() - 86400000L * 365)); /** The maximum possible value in X.509 specification: 9999-12-31 23:59:59 */ private static final Date DEFAULT_NOT_AFTER = new Date(SystemPropertyUtil.getLong( "io.netty.selfSignedCertificate.defaultNotAfter", 253402300799000L)); private final File certificate; private final File privateKey; private final X509Certificate cert; private final PrivateKey key; /** * Creates a new instance. */ public SelfSignedCertificate() throws CertificateException { this(DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER); } /** * Creates a new instance. * @param notBefore Certificate is not valid before this time * @param notAfter Certificate is not valid after this time */ public SelfSignedCertificate(Date notBefore, Date notAfter) throws CertificateException { this("example.com", notBefore, notAfter); } /** * Creates a new instance. * * @param fqdn a fully qualified domain name */ public SelfSignedCertificate(String fqdn) throws CertificateException { this(fqdn, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER); } /** * Creates a new instance. * * @param fqdn a fully qualified domain name * @param notBefore Certificate is not valid before this time * @param notAfter Certificate is not valid after this time */ public SelfSignedCertificate(String fqdn, Date notBefore, Date notAfter) throws CertificateException { // Bypass entrophy collection by using insecure random generator. // We just want to generate it without any delay because it's for testing purposes only. this(fqdn, ThreadLocalInsecureRandom.current(), 1024, notBefore, notAfter); } /** * Creates a new instance. * * @param fqdn a fully qualified domain name * @param random the {@link java.security.SecureRandom} to use * @param bits the number of bits of the generated private key */ public SelfSignedCertificate(String fqdn, SecureRandom random, int bits) throws CertificateException { this(fqdn, random, bits, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER); } /** * Creates a new instance. * * @param fqdn a fully qualified domain name * @param random the {@link java.security.SecureRandom} to use * @param bits the number of bits of the generated private key * @param notBefore Certificate is not valid before this time * @param notAfter Certificate is not valid after this time */ public SelfSignedCertificate(String fqdn, SecureRandom random, int bits, Date notBefore, Date notAfter) throws CertificateException { // Generate an RSA key pair. final KeyPair keypair; try { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(bits, random); keypair = keyGen.generateKeyPair(); } catch (NoSuchAlgorithmException e) { // Should not reach here because every Java implementation must have RSA key pair generator. throw new Error(e); } String[] paths; try { // Try the OpenJDK's proprietary implementation. paths = OpenJdkSelfSignedCertGenerator.generate(fqdn, keypair, random, notBefore, notAfter); } catch (Throwable t) { logger.debug("Failed to generate a self-signed X.509 certificate using sun.security.x509:", t); try { // Try Bouncy Castle if the current JVM didn't have sun.security.x509. paths = BouncyCastleSelfSignedCertGenerator.generate(fqdn, keypair, random, notBefore, notAfter); } catch (Throwable t2) { logger.debug("Failed to generate a self-signed X.509 certificate using Bouncy Castle:", t2); throw new CertificateException( "No provider succeeded to generate a self-signed certificate. " + "See debug log for the root cause."); } } certificate = new File(paths[0]); privateKey = new File(paths[1]); key = keypair.getPrivate(); FileInputStream certificateInput = null; try { certificateInput = new FileInputStream(certificate); cert = (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(certificateInput); } catch (Exception e) { throw new CertificateEncodingException(e); } finally { if (certificateInput != null) { try { certificateInput.close(); } catch (IOException e) { logger.warn("Failed to close a file: " + certificate, e); } } } } /** * Returns the generated X.509 certificate file in PEM format. */ public File certificate() { return certificate; } /** * Returns the generated RSA private key file in PEM format. */ public File privateKey() { return privateKey; } /** * Returns the generated X.509 certificate. */ public X509Certificate cert() { return cert; } /** * Returns the generated RSA private key. */ public PrivateKey key() { return key; } /** * Deletes the generated X.509 certificate file and RSA private key file. */ public void delete() { safeDelete(certificate); safeDelete(privateKey); } static String[] newSelfSignedCertificate( String fqdn, PrivateKey key, X509Certificate cert) throws IOException, CertificateEncodingException { // Encode the private key into a file. ByteBuf wrappedBuf = Unpooled.wrappedBuffer(key.getEncoded()); ByteBuf encodedBuf; final String keyText; try { encodedBuf = Base64.encode(wrappedBuf, true); try { keyText = "-----BEGIN PRIVATE KEY-----\n" + encodedBuf.toString(CharsetUtil.US_ASCII) + "\n-----END PRIVATE KEY-----\n"; } finally { encodedBuf.release(); } } finally { wrappedBuf.release(); } File keyFile = File.createTempFile("keyutil_" + fqdn + '_', ".key"); keyFile.deleteOnExit(); OutputStream keyOut = new FileOutputStream(keyFile); try { keyOut.write(keyText.getBytes(CharsetUtil.US_ASCII)); keyOut.close(); keyOut = null; } finally { if (keyOut != null) { safeClose(keyFile, keyOut); safeDelete(keyFile); } } wrappedBuf = Unpooled.wrappedBuffer(cert.getEncoded()); final String certText; try { encodedBuf = Base64.encode(wrappedBuf, true); try { // Encode the certificate into a CRT file. certText = "-----BEGIN CERTIFICATE-----\n" + encodedBuf.toString(CharsetUtil.US_ASCII) + "\n-----END CERTIFICATE-----\n"; } finally { encodedBuf.release(); } } finally { wrappedBuf.release(); } File certFile = File.createTempFile("keyutil_" + fqdn + '_', ".crt"); certFile.deleteOnExit(); OutputStream certOut = new FileOutputStream(certFile); try { certOut.write(certText.getBytes(CharsetUtil.US_ASCII)); certOut.close(); certOut = null; } finally { if (certOut != null) { safeClose(certFile, certOut); safeDelete(certFile); safeDelete(keyFile); } } return new String[] { certFile.getPath(), keyFile.getPath() }; } private static void safeDelete(File certFile) { if (!certFile.delete()) { logger.warn("Failed to delete a file: " + certFile); } } private static void safeClose(File keyFile, OutputStream keyOut) { try { keyOut.close(); } catch (IOException e) { logger.warn("Failed to close a file: " + keyFile, e); } } }

Other Java examples (source code examples)

Here is a short list of links related to this Java SelfSignedCertificate.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.