Skip to content

Instantly share code, notes, and snippets.

@Dviejopomata
Created January 29, 2018 08:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dviejopomata/3eac03d6f57d87b10fc3f70cc3ba80b9 to your computer and use it in GitHub Desktop.
Save Dviejopomata/3eac03d6f57d87b10fc3f70cc3ba80b9 to your computer and use it in GitHub Desktop.
Java para generar Ca con intermediate
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v1CertificateBuilder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
public class TestCerts {
private static char[] passwd = {'s', 'e', 'c', 'r', 'e', 't'};
private static String domain = "test.nextagiledev.com";
private static String organization = "NextAgileSoft Development";
private static String country = "ES";
/**
* we generate the CA's certificate
*/
public static Certificate createMasterCert(
PublicKey pubKey,
PrivateKey privKey)
throws Exception {
//
// signers name
//
String issuer = String.format("C=%s, O=%s, OU=Nextagilesoft Primary Certificate", country, organization);
//
// subjects name - the same as we are self signed.
//
String subject = String.format("C=%s, O=%s, OU=Nextagilesoft Primary Certificate", country, organization);
//
// create the certificate - version 1
//
X509v1CertificateBuilder v1Bldr = new JcaX509v1CertificateBuilder(new X500Name(issuer), BigInteger.valueOf(1),
new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)),
new X500Name(subject), pubKey);
X509CertificateHolder certHldr = v1Bldr.build(new JcaContentSignerBuilder("SHA256WithRSA").setProvider("BC").build(privKey));
X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHldr);
cert.checkValidity(new Date());
cert.verify(pubKey);
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;
//
// this is actually optional - but if you want to have control
// over setting the friendly name this is the way to do it...
//
bagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString("Nextagilesoft Primary Certificate"));
return cert;
}
/**
* we generate an intermediate certificate signed by our CA
*/
public static Certificate createIntermediateCert(
PublicKey pubKey,
PrivateKey caPrivKey,
X509Certificate caCert)
throws Exception {
//
// subject name builder.
//
X500NameBuilder nameBuilder = new X500NameBuilder();
nameBuilder.addRDN(BCStyle.C, "ES");
nameBuilder.addRDN(BCStyle.O, organization);
nameBuilder.addRDN(BCStyle.OU, "Nextagilesoft Intermediate Certificate");
nameBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org");
//
// create the certificate - version 3
//
X509v3CertificateBuilder v3Bldr = new JcaX509v3CertificateBuilder(caCert, BigInteger.valueOf(2),
new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)),
nameBuilder.build(), pubKey);
//
// extensions
//
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
v3Bldr.addExtension(
Extension.subjectKeyIdentifier,
false,
extUtils.createSubjectKeyIdentifier(pubKey));
v3Bldr.addExtension(
Extension.authorityKeyIdentifier,
false,
extUtils.createAuthorityKeyIdentifier(caCert));
v3Bldr.addExtension(
Extension.basicConstraints,
true,
new BasicConstraints(0));
X509CertificateHolder certHldr = v3Bldr.build(new JcaContentSignerBuilder("SHA256WithRSA").setProvider("BC").build(caPrivKey));
X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHldr);
cert.checkValidity(new Date());
cert.verify(caCert.getPublicKey());
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;
//
// this is actually optional - but if you want to have control
// over setting the friendly name this is the way to do it...
//
bagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString("Nextagilesoft Intermediate Certificate"));
return cert;
}
/**
* we generate a certificate signed by our CA's intermediate certificate
*/
public static Certificate createCert(
PublicKey pubKey,
PrivateKey caPrivKey,
PublicKey caPubKey)
throws Exception {
//
// signers name table.
//
X500NameBuilder issuerBuilder = new X500NameBuilder();
issuerBuilder.addRDN(BCStyle.C, country);
issuerBuilder.addRDN(BCStyle.O, organization);
issuerBuilder.addRDN(BCStyle.OU, "Nextagilesoft Intermediate Certificate");
issuerBuilder.addRDN(BCStyle.CN, "Nextagilesoft");
issuerBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org");
//
// subjects name table.
//
X500NameBuilder subjectBuilder = new X500NameBuilder();
subjectBuilder.addRDN(BCStyle.C, country);
subjectBuilder.addRDN(BCStyle.O, organization);
subjectBuilder.addRDN(BCStyle.L, "Alicante");
subjectBuilder.addRDN(BCStyle.CN, domain);
subjectBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org");
//
// create the certificate - version 3
//
X509v3CertificateBuilder v3Bldr = new JcaX509v3CertificateBuilder(issuerBuilder.build(), BigInteger.valueOf(3),
new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)),
subjectBuilder.build(), pubKey);
//
// extensions
//
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
v3Bldr.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(new GeneralName(GeneralName.dNSName, domain)));
v3Bldr.addExtension(
Extension.subjectKeyIdentifier,
false,
extUtils.createSubjectKeyIdentifier(pubKey));
v3Bldr.addExtension(
Extension.authorityKeyIdentifier,
false,
extUtils.createAuthorityKeyIdentifier(caPubKey));
X509CertificateHolder certHldr = v3Bldr.build(new JcaContentSignerBuilder("SHA256WithRSA").setProvider("BC").build(caPrivKey));
X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHldr);
cert.checkValidity(new Date());
cert.verify(caPubKey);
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;
//
// this is also optional - in the sense that if you leave this
// out the keystore will add it automatically, note though that
// for the browser to recognise the associated private key this
// you should at least use the pkcs_9_localKeyId OID and set it
// to the same as you do for the private key's localKeyId.
//
bagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString("Eric's Key"));
bagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
extUtils.createSubjectKeyIdentifier(pubKey));
return cert;
}
public static void main(
String[] args)
throws Exception {
Security.addProvider(new BouncyCastleProvider());
//
// set up the keys
//
final KeyPair caKp = CertsUtil.generateKeyPair();
PrivateKey caPrivKey = caKp.getPrivate();
PublicKey caPubKey = caKp.getPublic();
final KeyPair intKp = CertsUtil.generateKeyPair();
PrivateKey intPrivKey = intKp.getPrivate();
PublicKey intPubKey = intKp.getPublic();
final KeyPair certKp = CertsUtil.generateKeyPair();
PrivateKey privKey = certKp.getPrivate();
PublicKey pubKey = certKp.getPublic();
final KeyPair clientCertKp = CertsUtil.generateKeyPair();
PrivateKey clientPrivKey = clientCertKp.getPrivate();
PublicKey clientPubKey = clientCertKp.getPublic();
Certificate[] chain = new Certificate[3];
final Certificate masterCert = createMasterCert(caPubKey, caPrivKey);
CertsUtil.writeCert(masterCert, "./certs/ca.crt");
CertsUtil.writePk("./certs/ca.key", caKp);
chain[2] = masterCert;
final Certificate intermediateCert = createIntermediateCert(intPubKey, caPrivKey, (X509Certificate) chain[2]);
CertsUtil.writeCert(intermediateCert, "./certs/intermediate-ca.crt");
CertsUtil.writePk("./certs/intermediate-ca.key", intKp);
chain[1] = intermediateCert;
final Certificate cert = createCert(pubKey, intPrivKey, intPubKey);
CertsUtil.writeCert(cert, "./certs/server.crt");
CertsUtil.writePk("./certs/server.key", certKp);
chain[0] = cert;
// final Certificate clientCert = createCert(clientPubKey, caPrivKey, caPubKey);
// CertsUtil.writeCert(clientCert, "./certs/client.crt");
// CertsUtil.writePk("./certs/client.key", clientCertKp);
//
// add the friendly name for the private key
//
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) privKey;
//
// this is also optional - in the sense that if you leave this
// out the keystore will add it automatically, note though that
// for the browser to recognise which certificate the private key
// is associated with you should at least use the pkcs_9_localKeyId
// OID and set it to the same as you do for the private key's
// corresponding certificate.
//
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
bagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString("Development's Key"));
bagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
extUtils.createSubjectKeyIdentifier(pubKey));
//
// store the key and the certificate chain
//
KeyStore store = KeyStore.getInstance("PKCS12", "BC");
store.load(null, null);
//
// if you haven't set the friendly name and local key id above
// the name below will be the name of the key
//
store.setKeyEntry("Development's Key", privKey, null, chain);
FileOutputStream fOut = new FileOutputStream("id.p12");
store.store(fOut, passwd);
fOut.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment