Bouncy Castle has X509 Certificate builder but in my opinion it is still quite low tech.
package se.magnuskkarlsson.example.bouncycastle;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.util.Calendar;
import java.util.Date;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.DERUTF8String;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AccessDescription;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.CertificatePolicies;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.PolicyInformation;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
// org.bouncycastle.cert.X509v3CertificateBuilder
public class X509CertificateBuilder {
public static final ASN1ObjectIdentifier MSUPN_OID = new ASN1ObjectIdentifier("1.3.6.1.4.1.311.20.2.3");
private V3TBSCertificateGenerator tbsGen;
private ExtensionsGenerator extGenerator;
public X509CertificateBuilder() {
this.tbsGen = new V3TBSCertificateGenerator();
this.extGenerator = new ExtensionsGenerator();
}
// ----------------------- Logic Methods -----------------------
//
// Mandatory Fields
//
public X509CertificateBuilder setSerialNumber(BigInteger serialNumber) {
tbsGen.setSerialNumber(new ASN1Integer(serialNumber));
return this;
}
public X509CertificateBuilder setIssuerDN(X500Name issuerDN) {
this.tbsGen.setIssuer(issuerDN);
return this;
}
public X509CertificateBuilder setValidity(int numberOfYears) {
Date validityNotBefore = new Date(System.currentTimeMillis());
Calendar calendar = Calendar.getInstance();
calendar.setTime(validityNotBefore);
// calendar.add(Calendar.DAY_OF_YEAR, numberOfYears);
calendar.add(Calendar.YEAR, numberOfYears);
Date validityNotAfter = calendar.getTime();
this.tbsGen.setStartDate(new Time(validityNotBefore));
this.tbsGen.setEndDate(new Time(validityNotAfter));
return this;
}
public X509CertificateBuilder setSubjectDN(X500Name subjectDN) {
this.tbsGen.setSubject(subjectDN);
return this;
}
public X509CertificateBuilder setSubjectPublicKeyInfo(PublicKey publicKey) {
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
this.tbsGen.setSubjectPublicKeyInfo(subjectPublicKeyInfo);
return this;
}
//
// Certificate Extensions
//
public X509CertificateBuilder setBasicContraints(boolean ca, boolean critical) throws IOException {
this.extGenerator.addExtension(Extension.basicConstraints, critical, new BasicConstraints(ca));
return this;
}
public X509CertificateBuilder setAuthorityKeyIdentifier(PublicKey caPublicKey, boolean critical)
throws NoSuchAlgorithmException, IOException {
this.extGenerator.addExtension(Extension.authorityKeyIdentifier, critical,
new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(caPublicKey));
return this;
}
public X509CertificateBuilder setSubjectKeyIdentifier(PublicKey publicKey, boolean critical)
throws NoSuchAlgorithmException, IOException {
this.extGenerator.addExtension(Extension.subjectKeyIdentifier, critical,
new JcaX509ExtensionUtils().createSubjectKeyIdentifier(publicKey));
return this;
}
public X509CertificateBuilder setAuthorityInformationAccess(String ocspUri, String caIssuersUri, boolean critical)
throws IOException {
GeneralName ocspName = new GeneralName(GeneralName.uniformResourceIdentifier, ocspUri);
GeneralName caIssuersName = new GeneralName(GeneralName.uniformResourceIdentifier, caIssuersUri);
AccessDescription ocsp = new AccessDescription(AccessDescription.id_ad_ocsp, ocspName);
AccessDescription caIssuers = new AccessDescription(AccessDescription.id_ad_caIssuers, caIssuersName);
AuthorityInformationAccess authorityInformationAccess = new AuthorityInformationAccess(
new AccessDescription[] { ocsp, caIssuers });
this.extGenerator.addExtension(Extension.authorityInfoAccess, critical, authorityInformationAccess);
return this;
}
public X509CertificateBuilder setCRLDistributionPoints(String cdpUri, boolean critical) throws IOException {
GeneralNames generalNames = new GeneralNames(new GeneralName(GeneralName.uniformResourceIdentifier, cdpUri));
DistributionPoint[] distPoints = new DistributionPoint[] {
new DistributionPoint(new DistributionPointName(generalNames), null, null) };
this.extGenerator.addExtension(Extension.cRLDistributionPoints, critical, new CRLDistPoint(distPoints));
return this;
}
public X509CertificateBuilder setCertificatePolicies(String[] certificatePolicyIds, boolean critical)
throws IOException {
PolicyInformation[] policyInfos = new PolicyInformation[certificatePolicyIds.length];
for (int i = 0; i < certificatePolicyIds.length; ++i) {
policyInfos[i] = new PolicyInformation(new ASN1ObjectIdentifier(certificatePolicyIds[i]));
}
this.extGenerator.addExtension(Extension.certificatePolicies, critical, new CertificatePolicies(policyInfos));
return this;
}
public X509CertificateBuilder setKeyUsage(KeyUsage keyUsage1, boolean critical) throws IOException {
this.extGenerator.addExtension(Extension.keyUsage, critical,
new org.bouncycastle.asn1.x509.KeyUsage(keyUsage1.getValue()));
return this;
}
public X509CertificateBuilder setKeyUsage(KeyUsage keyUsage1, KeyUsage keyUsage2, boolean critical)
throws IOException {
this.extGenerator.addExtension(Extension.keyUsage, critical,
new org.bouncycastle.asn1.x509.KeyUsage(keyUsage1.getValue() | keyUsage2.getValue()));
return this;
}
public X509CertificateBuilder setKeyUsage(KeyUsage keyUsage1, KeyUsage keyUsage2, KeyUsage keyUsage3,
boolean critical) throws IOException {
this.extGenerator.addExtension(Extension.keyUsage, critical, new org.bouncycastle.asn1.x509.KeyUsage(
keyUsage1.getValue() | keyUsage2.getValue() | keyUsage3.getValue()));
return this;
}
public X509CertificateBuilder setExtendedKeyUsage(KeyPurposeId[] keyPurposeIds, boolean critical)
throws IOException {
this.extGenerator.addExtension(Extension.extendedKeyUsage, critical, new ExtendedKeyUsage(keyPurposeIds));
return this;
}
public X509CertificateBuilder setSubjectAlternativeNamesDNS(String[] hostnames, boolean critical)
throws IOException {
GeneralName[] generalNames = new GeneralName[hostnames.length];
for (int i = 0; i < hostnames.length; ++i) {
generalNames[i] = new GeneralName(GeneralName.dNSName, hostnames[i]);
}
this.extGenerator.addExtension(Extension.subjectAlternativeName, critical, new GeneralNames(generalNames));
return this;
}
public X509CertificateBuilder setSubjectAlternativeNamesUPN(String upn, boolean critical) throws IOException {
this.extGenerator.addExtension(Extension.subjectAlternativeName, critical, new GeneralNames(new GeneralName(
GeneralName.otherName,
new DERSequence(new ASN1Encodable[] { MSUPN_OID, new DERTaggedObject(0, new DERUTF8String(upn)) }))));
return this;
}
public java.security.cert.X509Certificate build(PrivateKey caPrivateKey, String signatureAlgorithm)
throws OperatorCreationException, CertificateException, NoSuchAlgorithmException, IOException {
ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm)
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(caPrivateKey);
this.tbsGen.setSignature(contentSigner.getAlgorithmIdentifier());
this.tbsGen.setExtensions(this.extGenerator.generate());
TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
X509CertificateHolder X509CertificateHolder = new X509CertificateHolder(generateStructure(tbsCert,
contentSigner.getAlgorithmIdentifier(), generateSig(contentSigner, tbsCert)));
return new JcaX509CertificateConverter().getCertificate(X509CertificateHolder);
}
// ----------------------- Helper Methods -----------------------
// org.bouncycastle.asn1.x509.KeyUsage
public enum KeyUsage {
DIGITAL_SIGNATURE(org.bouncycastle.asn1.x509.KeyUsage.digitalSignature), //
NON_REPUDIATION(org.bouncycastle.asn1.x509.KeyUsage.nonRepudiation), //
KEY_ENCIPHERMENT(org.bouncycastle.asn1.x509.KeyUsage.keyEncipherment), //
DATA_ENCIPHERMENT(org.bouncycastle.asn1.x509.KeyUsage.dataEncipherment), //
KEY_AGREEMENT(org.bouncycastle.asn1.x509.KeyUsage.keyAgreement), //
KEY_CERT_SIGN(org.bouncycastle.asn1.x509.KeyUsage.keyCertSign), //
CRL_SIGN(org.bouncycastle.asn1.x509.KeyUsage.cRLSign);
private final int value;
KeyUsage(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
protected byte[] generateSig(ContentSigner signer, ASN1Object tbsObj) throws IOException {
OutputStream sOut = signer.getOutputStream();
tbsObj.encodeTo(sOut, ASN1Encoding.DER);
sOut.close();
return signer.getSignature();
}
protected Certificate generateStructure(TBSCertificate tbsCert, AlgorithmIdentifier sigAlgId, byte[] signature) {
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(tbsCert);
v.add(sigAlgId);
v.add(new DERBitString(signature));
return Certificate.getInstance(new DERSequence(v));
}
// ----------------------- Get and Set Methods -----------------------
}
And certificate profile builder.
package se.magnuskkarlsson.example.bouncycastle;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.operator.OperatorCreationException;
import se.magnuskkarlsson.example.bouncycastle.X509CertificateBuilder.KeyUsage;
public class X509CertificateProfile {
// ----------------------- Logic Methods -----------------------
public X509Certificate createCA(KeyPair caKeyPair, X500Name subjectDN, String cdpUri)
throws OperatorCreationException, CertificateException, NoSuchAlgorithmException, IOException {
return new X509CertificateBuilder() //
// mandatory fields
.setSerialNumber(getSerialNumber()) //
.setIssuerDN(subjectDN) //
.setValidity(10) //
.setSubjectDN(subjectDN) //
.setSubjectPublicKeyInfo(caKeyPair.getPublic()) //
// certificate extensions
.setBasicContraints(true, true) //
.setAuthorityKeyIdentifier(caKeyPair.getPublic(), false) //
.setSubjectKeyIdentifier(caKeyPair.getPublic(), false) //
.setCRLDistributionPoints(cdpUri, false) //
.setKeyUsage(KeyUsage.DIGITAL_SIGNATURE, KeyUsage.KEY_CERT_SIGN, KeyUsage.CRL_SIGN, true) //
.build(caKeyPair.getPrivate(), CAKeyStore.SHA256_RSA_SIGNATURE);
}
public X509Certificate createServer(KeyPair caKeyPair, KeyPair keyPair, X500Name issuerDN, X500Name subjectDN,
String ocspUri, String caIssuersUri, String cdpUri, String[] hostnames)
throws OperatorCreationException, CertificateException, NoSuchAlgorithmException, IOException {
return new X509CertificateBuilder() //
// mandatory fields
.setSerialNumber(getSerialNumber()) //
.setIssuerDN(issuerDN) //
.setValidity(1) //
.setSubjectDN(subjectDN) //
.setSubjectPublicKeyInfo(keyPair.getPublic()) //
// certificate extensions
.setBasicContraints(false, true) //
.setAuthorityKeyIdentifier(caKeyPair.getPublic(), false) //
.setSubjectKeyIdentifier(keyPair.getPublic(), false) //
.setAuthorityInformationAccess(ocspUri, caIssuersUri, false) //
.setCRLDistributionPoints(cdpUri, false) //
.setKeyUsage(KeyUsage.DIGITAL_SIGNATURE, KeyUsage.KEY_ENCIPHERMENT, false) //
.setExtendedKeyUsage(new KeyPurposeId[] { KeyPurposeId.id_kp_serverAuth }, false)
.setSubjectAlternativeNamesDNS(hostnames, false) //
.build(caKeyPair.getPrivate(), CAKeyStore.SHA256_RSA_SIGNATURE);
}
public X509Certificate createClient(KeyPair caKeyPair, KeyPair keyPair, X500Name issuerDN, X500Name subjectDN,
String ocspUri, String caIssuersUri, String cdpUri, String upn)
throws OperatorCreationException, CertificateException, NoSuchAlgorithmException, IOException {
return new X509CertificateBuilder() //
// mandatory fields
.setSerialNumber(getSerialNumber()) //
.setIssuerDN(issuerDN) //
.setValidity(1) //
.setSubjectDN(subjectDN) //
.setSubjectPublicKeyInfo(keyPair.getPublic()) //
// certificate extensions
.setBasicContraints(false, true) //
.setAuthorityKeyIdentifier(caKeyPair.getPublic(), false) //
.setSubjectKeyIdentifier(keyPair.getPublic(), false) //
.setAuthorityInformationAccess(ocspUri, caIssuersUri, false) //
.setCRLDistributionPoints(cdpUri, false) //
.setKeyUsage(KeyUsage.DIGITAL_SIGNATURE, KeyUsage.NON_REPUDIATION, KeyUsage.KEY_ENCIPHERMENT, true) //
.setExtendedKeyUsage(new KeyPurposeId[] { KeyPurposeId.id_kp_clientAuth }, false)
.setSubjectAlternativeNamesUPN(upn, false) //
.build(caKeyPair.getPrivate(), CAKeyStore.SHA256_RSA_SIGNATURE);
}
// ----------------------- Helper Methods -----------------------
protected BigInteger getSerialNumber() {
// RFC 5280 and X.690
// Effective September 30, 2016, CAs SHALL generate non-sequential Certificate serial numbers greater than zero
// (0) containing at least 64 bits of output from a CSPRNG.
return BigInteger.valueOf(System.currentTimeMillis());
}
// ----------------------- Get and Set Methods -----------------------
}
And unit test.
package se.magnuskkarlsson.example.bouncycastle;
import java.io.File;
import java.security.KeyPair;
import java.security.Security;
import java.security.cert.X509Certificate;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class X509CertificateProfileTest {
private static KeyPair caKeyPair;
private static X500Name caSubjectDN;
private String ocspUri = "http://ocsp.mkk.se/";
private String caIssuersUri = "http://pki.mkk.se/ca.crt";
private String cdpUri = "http://crl.mkk.se/ca.crl";
@BeforeClass
public static void oneTimeSetUp() throws Exception {
Security.addProvider(new BouncyCastleProvider());
caKeyPair = new CAKeyStore(new Configurations()).createKeyPair(CAKeyStore.RSA_ALGORITHM, 4096);
caSubjectDN = new X500NameBuilder() //
.addRDN(BCStyle.CN, "FOO CA") //
.addRDN(BCStyle.O, "MKK") //
.addRDN(BCStyle.C, "SE") //
.build();
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() {
}
@AfterClass
public static void oneTimeTearDown() throws Exception {
}
// ----------------------- Test Methods -----------------------
@Test
public void createCA() throws Exception {
X509Certificate caCert = new X509CertificateProfile().createCA(caKeyPair, caSubjectDN, cdpUri);
System.out.println(caCert);
EncryptionUtils.writePEM(caCert, File.createTempFile("caCert-", ".crt.pem"));
}
@Test
public void createServer() throws Exception {
KeyPair serverKeyPair = new CAKeyStore(new Configurations()).createKeyPair(CAKeyStore.RSA_ALGORITHM, 2048);
X500Name serverSubjectDN = new X500NameBuilder() //
.addRDN(BCStyle.CN, "FQDN") //
.addRDN(BCStyle.OU, "mywebapp") //
.addRDN(BCStyle.O, "MKK") //
.addRDN(BCStyle.C, "SE") //
.build();
String[] hostnames = new String[] { "localhost", "127.0.0.1" };
X509Certificate serverCert = new X509CertificateProfile().createServer(caKeyPair, serverKeyPair, caSubjectDN,
serverSubjectDN, ocspUri, caIssuersUri, cdpUri, hostnames);
System.out.println(serverCert);
EncryptionUtils.writePEM(serverCert, File.createTempFile("serverCert-", ".crt.pem"));
}
@Test
public void createClient() throws Exception {
X509Certificate caCert = new X509CertificateProfile().createCA(caKeyPair, caSubjectDN, cdpUri);
KeyPair clientKeyPair = new CAKeyStore(new Configurations()).createKeyPair(CAKeyStore.RSA_ALGORITHM, 2048);
X500Name clientSubjectDN = new X500NameBuilder() //
.addRDN(BCStyle.CN, "Magnus K Karlsson") //
.addRDN(BCStyle.OU, "1000") //
.addRDN(BCStyle.O, "MKK") //
.addRDN(BCStyle.C, "SE") //
.build();
String upn = "1000@mkk.se";
X509Certificate clientCert = new X509CertificateProfile().createClient(caKeyPair, clientKeyPair, caSubjectDN,
clientSubjectDN, ocspUri, caIssuersUri, cdpUri, upn);
System.out.println(clientCert);
EncryptionUtils.writePEM(clientCert, File.createTempFile("clientCert-", ".cert.pem"));
System.out.println(EncryptionUtils.getMSUPN(clientCert));
EncryptionUtils.writeKeyStore("PKCS12", clientKeyPair.getPrivate(), "changeit",
new X509Certificate[] { clientCert, caCert }, File.createTempFile("clientCert-", ".p12"));
}
}
And when run.
[
[
Version: V3
Subject: C=SE, O=MKK, OU=1000, CN=Magnus K Karlsson
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
params: null
modulus: 25571568211886603124840374772893412632803008320276441343266420556001859527212495329059106511242070860135631150070936589994653782417968024014212169649126808218158560179639047989539457693799118359900429037050920421546627123472786524557783697159392478858239658746621633838155562268034256430543588459559201972100435495705680421356703692111342204230448132868538272476016901917159213800485636336183819543618065791989738031811366034365221624184676389882604646322575407826629234052470133086130458566129601941794090632783578168688778972919128563980379914647410944834699287955276441401709227130144873341655798718948150387040663
public exponent: 65537
Validity: [From: Mon Mar 02 20:35:28 CET 2020,
To: Tue Mar 02 20:35:28 CET 2021]
Issuer: C=SE, O=MKK, CN=FOO CA
SerialNumber: [ 01709cbf 0140]
Certificate Extensions: 8
[1]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[
accessMethod: ocsp
accessLocation: URIName: http://ocsp.mkk.se/
,
accessMethod: caIssuers
accessLocation: URIName: http://pki.mkk.se/ca.crt
]
]
[2]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 13 5B F4 D2 4E 05 F0 73 9D D0 60 C4 42 A3 80 95 .[..N..s..`.B...
0010: 37 7B 9A 1B 7...
]
]
[3]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]
[4]: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
[DistributionPoint:
[URIName: http://crl.mkk.se/ca.crl]
]]
[5]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
clientAuth
]
[6]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Non_repudiation
Key_Encipherment
]
[7]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
Other-Name: Unrecognized ObjectIdentifier: 1.3.6.1.4.1.311.20.2.3
]
[8]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 63 31 5B A3 22 8C C0 4B DF 2D 7B 39 4C 43 D2 DB c1[."..K.-.9LC..
0010: 11 96 37 46 ..7F
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 85 9B 22 22 44 4E E0 59 44 31 12 53 39 D5 A4 78 ..""DN.YD1.S9..x
0010: DA 39 80 BC 53 47 94 D1 B3 B6 E3 2B 8F D4 39 92 .9..SG.....+..9.
0020: 7B 63 CE FA 48 53 33 BF B6 4B E7 83 90 47 AA 2D .c..HS3..K...G.-
0030: 32 B6 02 9F A9 1B EE 27 02 7C 68 B2 9F 50 D4 D2 2......'..h..P..
0040: 55 2C A4 B6 1C 09 F1 BF AE 0A A6 39 60 DE 93 CA U,.........9`...
0050: 74 32 54 8F 74 E0 5B F8 0D 32 FE 6E 02 6B 88 9D t2T.t.[..2.n.k..
0060: 2F D7 0C 9D A7 DE 20 5B 10 0A 08 61 1A 76 B0 35 /..... [...a.v.5
0070: 80 E3 AF C6 4C A9 06 E0 38 2F 9F D8 48 E8 BE DC ....L...8/..H...
0080: 89 C0 DF 64 E2 F3 72 3C BC 51 A8 D9 F2 1E 18 4A ...d..r<.Q.....J
0090: 1B 52 1D E1 2E D7 EA 23 37 4C CA 4C A6 8A E6 85 .R.....#7L.L....
00A0: 60 7D 29 63 4F A0 90 37 29 EE CF 0E 0E 05 0E 85 `.)cO..7).......
00B0: 93 47 63 BC 7C CF CE 58 58 71 72 56 76 45 63 0A .Gc....XXqrVvEc.
00C0: D6 33 BD EF 53 9A 8C F1 19 EE E7 AE 8E 8E 76 A0 .3..S.........v.
00D0: 37 7B BE 45 B5 C8 7B 72 FD 29 8B 80 0B 74 5E 24 7..E...r.)...t^$
00E0: 71 66 3D C9 39 A0 6B 24 B2 91 09 57 9C B7 2D 2E qf=.9.k$...W..-.
00F0: 82 B8 D7 CA 7A 71 CF 05 2C 97 89 76 DC 3D 2A B8 ....zq..,..v.=*.
0100: 10 A0 8C 27 8D 49 2A 23 C9 8E FB D1 2B 55 00 6D ...'.I*#....+U.m
0110: 76 CE 2D 86 8A E1 4D B4 1C 9E 8C 47 15 BC 7F DF v.-...M....G....
0120: 20 23 D1 09 27 A3 DB 9B 7F AC D9 AE D7 72 D3 A3 #..'........r..
0130: E0 20 63 91 1A 49 A6 77 3E B2 EE F0 B1 57 8D 77 . c..I.w>....W.w
0140: 62 11 3C E2 17 28 6F CB BE 44 14 A3 06 23 89 74 b.<..(o..D...#.t
0150: DE 05 75 DC CB D7 2A 86 3D 9A FA 29 94 00 82 09 ..u...*.=..)....
0160: 3D B1 DE A9 12 F1 48 30 F2 5C 52 10 0D 81 CA 5A =.....H0.\R....Z
0170: 69 8A 9B F5 3B 7A F4 CB 8A D7 51 AE 5A CD A1 51 i...;z....Q.Z..Q
0180: FA F8 66 AF FC 02 68 2D E9 CC D7 AF C1 FA 21 84 ..f...h-......!.
0190: 0C 1B 7A 0F DE B9 3D 9A 8A 1A 61 BC 46 01 3A FD ..z...=...a.F.:.
01A0: 62 E3 79 35 07 66 64 A7 17 83 5E 82 E9 93 A2 FA b.y5.fd...^.....
01B0: 6F D7 83 38 99 5F 44 69 6C AA F3 32 E4 B4 48 59 o..8._Dil..2..HY
01C0: 50 EC 64 14 72 51 9A E9 95 BC 4E CE EA 98 B3 BD P.d.rQ....N.....
01D0: 7C F4 BD D2 60 D3 07 7C 71 26 24 55 94 E5 AA D5 ....`...q&$U....
01E0: 44 A1 8D AC 30 AE 47 CA FF 96 FD CA 9E 03 25 EC D...0.G.......%.
01F0: 55 5B 97 5B 27 24 A3 23 8F 0D CD 9A DC 52 29 BA U[.['$.#.....R).
]
Mar 02, 2020 8:35:28 PM se.magnuskkarlsson.example.bouncycastle.EncryptionUtils writePEM
INFO: Wrote /tmp/clientCert-9146518211353882041.cert.pem
Mar 02, 2020 8:35:28 PM se.magnuskkarlsson.example.bouncycastle.EncryptionUtils getMSUPN
INFO: Read X509 SAN [[0, [1.3.6.1.4.1.311.20.2.3, [0]1000@mkk.se]]]
1000@mkk.se
Mar 02, 2020 8:35:28 PM se.magnuskkarlsson.example.bouncycastle.EncryptionUtils writeKeyStore
INFO: Wrote /tmp/clientCert-14620146327205577598.p12
[
[
Version: V3
Subject: C=SE, O=MKK, OU=mywebapp, CN=FQDN
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
params: null
modulus: 23472554064383360225540326318244541407904103528288156342671235877676704006249990542080185400202587647452428079635384512450814661982177331214162132359638484764547017758245274776079283522876250682767182225000730754889702275736425322221042334223219623764657811814147865593555449798942802445890347917633973214547390327111222760190458870434688746315828193389701570278446761804026480172159526376218012304574882822703261195947214666386714673839238432567588108434506291951836819612851494156727230958145708637864415669786989760083242288799613934351495483902217961576331883073677917645326766725734237025938297058790630425487583
public exponent: 65537
Validity: [From: Mon Mar 02 20:35:28 CET 2020,
To: Tue Mar 02 20:35:28 CET 2021]
Issuer: C=SE, O=MKK, CN=FOO CA
SerialNumber: [ 01709cbf 02ae]
Certificate Extensions: 8
[1]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[
accessMethod: ocsp
accessLocation: URIName: http://ocsp.mkk.se/
,
accessMethod: caIssuers
accessLocation: URIName: http://pki.mkk.se/ca.crt
]
]
[2]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 13 5B F4 D2 4E 05 F0 73 9D D0 60 C4 42 A3 80 95 .[..N..s..`.B...
0010: 37 7B 9A 1B 7...
]
]
[3]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]
[4]: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
[DistributionPoint:
[URIName: http://crl.mkk.se/ca.crl]
]]
[5]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
serverAuth
]
[6]: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
DigitalSignature
Key_Encipherment
]
[7]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
DNSName: localhost
DNSName: 127.0.0.1
]
[8]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: C4 54 8A E7 43 33 30 53 AD B5 7F 07 81 57 17 3F .T..C30S.....W.?
0010: 74 B2 6A 97 t.j.
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 5D C5 A5 AC 37 CA F7 AE A8 34 80 C7 17 DF 27 01 ]...7....4....'.
0010: 12 C1 CB 8A 8D 85 77 98 01 EB FD 44 21 63 1F 98 ......w....D!c..
0020: 51 69 67 E8 96 16 AA CF 9C 2A 6A 10 8B 3B F4 60 Qig......*j..;.`
0030: 8D 5C 66 46 6C E4 C4 A8 A0 60 A6 3E 43 35 40 FC .\fFl....`.>C5@.
0040: 77 5C 9A DA 13 D8 F9 F1 63 35 FD 0F 4B 6C A4 11 w\......c5..Kl..
0050: 5D 67 CF DA 73 9B E0 A0 35 05 6E 37 7A D9 E2 AF ]g..s...5.n7z...
0060: 10 80 A1 CA F5 5F D4 01 A7 6B 76 92 99 2F 74 25 ....._...kv../t%
0070: A6 27 D2 67 05 07 D9 E6 27 58 E6 90 D1 C0 2D B1 .'.g....'X....-.
0080: 7A 1B F9 5B 91 6E BE DD AB A8 AA EB B4 BB AE 96 z..[.n..........
0090: 9E 26 A8 CB 31 CE 4B 02 BE EA D4 6A AC B5 E5 FA .&..1.K....j....
00A0: 43 76 E4 8E C9 16 BF 55 34 E6 D0 A8 FA 1C 6D 48 Cv.....U4.....mH
00B0: C9 54 65 37 84 89 F6 13 C4 FD 0C 62 41 FF 57 5B .Te7.......bA.W[
00C0: 88 28 35 AF 83 1C D1 A3 8C A4 1F 7F CD E0 F4 F9 .(5.............
00D0: DA 64 C2 C3 51 D7 C5 56 2C 3D 6C A3 C0 B1 40 1B .d..Q..V,=l...@.
00E0: 2E 42 B5 6F FF 86 2F DB F2 1F E6 E0 24 A1 CD 7C .B.o../.....$...
00F0: A6 94 20 95 B8 95 74 05 0B 0E CE 08 43 2E CF FA .. ...t.....C...
0100: 43 EE 30 3B 40 2C 3E 10 4F BD B2 BC 48 55 07 23 C.0;@,>.O...HU.#
0110: 2B 06 FB F0 E5 76 A2 15 1D E1 8A 33 E6 76 A2 30 +....v.....3.v.0
0120: 6C 07 4C 2A B4 57 C3 62 51 DE 58 1A 5D 82 11 84 l.L*.W.bQ.X.]...
0130: 3F AF EE 17 EC 8B C9 8F EA F8 6F E4 C1 6A 1F C8 ?.........o..j..
0140: 41 2A 15 62 4C DC 99 37 49 9E 58 1D 95 E1 A6 2E A*.bL..7I.X.....
0150: AC F4 D3 4F 7F 44 87 B8 18 CD 34 D0 C5 85 9B A6 ...O.D....4.....
0160: C1 46 CD 68 80 84 BE F0 1D F0 E2 B2 2F 0E D3 A6 .F.h......../...
0170: DB 68 89 FD 4A F8 A5 35 AA CB 6A CC FA 45 9E 20 .h..J..5..j..E.
0180: 9D AA 1D 04 2F 14 8D D0 A4 2B 78 09 9A 23 DA 44 ..../....+x..#.D
0190: 65 76 54 CF D3 7B 7F 37 78 46 18 45 60 98 0D 63 evT....7xF.E`..c
01A0: 2A 7D F8 0D A6 0C 0B 1A 81 61 B8 2B 1F A3 92 E9 *........a.+....
01B0: F2 9C 5B 26 E9 81 50 6F D9 79 8B 03 54 64 6C EB ..[&..Po.y..Tdl.
01C0: AA 4A A1 B6 B3 6F 82 C8 20 9D D1 33 D5 D3 87 DA .J...o.. ..3....
01D0: 5A 3E 93 2A 22 FA BE 0A A8 1F B6 A4 5C AA E0 73 Z>.*".......\..s
01E0: 17 76 73 33 61 B0 7E ED 09 5E FD DB 4F B7 5A B4 .vs3a....^..O.Z.
01F0: 76 21 1B FA 43 F0 52 AE 78 DC 3B 09 06 66 45 B2 v!..C.R.x.;..fE.
]
Mar 02, 2020 8:35:28 PM se.magnuskkarlsson.example.bouncycastle.EncryptionUtils writePEM
INFO: Wrote /tmp/serverCert-12014046357869706442.crt.pem
[
[
Version: V3
Subject: C=SE, O=MKK, CN=FOO CA
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 4096 bits
params: null
modulus: 618097494562805236224635134817934912453172250162709722041733040687097334018651185958049454716082071938067246709420916424794899282956550425042006414596550620844500042869814998708415847406596390541333435551567170239109985394967160893875673187989640416587377196814478200867973805718141593244866119267189530684758333327813430426324393329942084968006256517216438373301377640102657162289647735616023682850661875444729876016663906609090034297679982852109216895370934293109110480164998867564217281544316832079056015576106175918287779836237538131308742105170670592053973122534872165219807886684564067083803402486128679568799840125501397600441124322949161232699891631680388114085515962034617420771247637630876469717153740862760325747621475058600558255078199328046206047780514609430807802825141363344880107809474319017977033492293123813011848757820259401796458615662171411629964165721128392643210117405003344910890867964280963490337780332547309122266515542815534797820516503892594199239179401978336582637760762233031975748737882775045900183794816021065220038962704464619646627020923143975929999810020514328195611426571022736233127780297192743641966846131645647190538362059522204380559481497214913394154203383211767929658852311603605904982991909
public exponent: 65537
Validity: [From: Mon Mar 02 20:35:28 CET 2020,
To: Sat Mar 02 20:35:28 CET 2030]
Issuer: C=SE, O=MKK, CN=FOO CA
SerialNumber: [ 01709cbf 02c1]
Certificate Extensions: 5
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 13 5B F4 D2 4E 05 F0 73 9D D0 60 C4 42 A3 80 95 .[..N..s..`.B...
0010: 37 7B 9A 1B 7...
]
]
[2]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
[3]: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
[DistributionPoint:
[URIName: http://crl.mkk.se/ca.crl]
]]
[4]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_CertSign
Crl_Sign
]
[5]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 13 5B F4 D2 4E 05 F0 73 9D D0 60 C4 42 A3 80 95 .[..N..s..`.B...
0010: 37 7B 9A 1B 7...
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 6B 5A 8D 8E 93 F0 97 BC 6C 62 DD 1A 65 22 75 10 kZ......lb..e"u.
0010: D1 E3 95 AF BA B8 C1 93 45 C9 44 0A EB 36 93 A8 ........E.D..6..
0020: FD 3C 6F 62 28 FF 59 68 14 8E 7E 45 BB 8E C9 68 .<ob(.Yh...E...h
0030: 0C F3 ED 7F 6D E1 9B FC D1 22 58 06 FB 6A EF ED ....m...."X..j..
0040: DC 34 E9 BA CD 7C 69 A9 73 FB F7 C6 7C FD 7A 43 .4....i.s.....zC
0050: 86 68 8A B9 10 F7 36 BC 1E E5 98 99 C4 1A 9D 43 .h....6........C
0060: 31 00 3B 22 38 BB 7E 96 1C 32 E6 8C 67 F4 66 3A 1.;"8....2..g.f:
0070: 37 D9 58 24 18 74 30 40 9C 4B 0C 23 BE 11 4E B1 7.X$.t0@.K.#..N.
0080: 11 4F AD 1D F2 C0 94 1D B3 B1 A5 CB FE C9 86 5B .O.............[
0090: 39 80 C9 B1 86 5A 0F 76 C9 4A 54 04 CC 0D 3B E0 9....Z.v.JT...;.
00A0: 94 0F 51 86 8F D8 5E FE 81 21 20 B7 38 9E 91 C4 ..Q...^..! .8...
00B0: FE B3 78 67 80 BF 0E 95 4F C7 E8 48 59 DB CA 43 ..xg....O..HY..C
00C0: E7 69 48 52 C1 78 DA 89 E1 2E 98 63 5E 5A B5 E6 .iHR.x.....c^Z..
00D0: 7B C5 DB D6 B9 35 4E 8A 52 5E 6F 22 EA AD CE 8E .....5N.R^o"....
00E0: 8C CF BF D3 41 0A 46 35 66 8A C1 E6 53 BE 1C 00 ....A.F5f...S...
00F0: EF 86 FE D7 C6 D9 62 EF 11 AC 44 49 6B 06 4E EC ......b...DIk.N.
0100: 59 1F 5B 03 D1 CC 63 2F 05 49 1A B4 B0 66 01 55 Y.[...c/.I...f.U
0110: 93 FF 89 CB F1 DA 1E E5 3A 21 E1 81 A5 9D E1 A5 ........:!......
0120: A5 5F 3D AF CF 7C 88 B6 F9 03 EF C8 23 A5 04 3F ._=.........#..?
0130: F6 CE EE 3A AB A0 A2 7F 0D 33 69 18 E3 A2 22 D8 ...:.....3i...".
0140: 7A 2E 09 1A B2 E5 7A 7C EA 15 08 92 3D D5 D8 8A z.....z.....=...
0150: 83 AE 6F CC 4D 30 73 CB 30 A1 0D D1 CC 47 B8 16 ..o.M0s.0....G..
0160: E3 2A 4B 06 32 79 99 4C 1E DD 92 5A 7D CD CB F3 .*K.2y.L...Z....
0170: 00 07 65 86 33 83 06 9C F9 5C 45 2C F9 F2 E7 36 ..e.3....\E,...6
0180: BB 78 8C 47 32 B6 A6 8B 6F 11 91 73 CF 92 EF B7 .x.G2...o..s....
0190: 60 22 12 48 2F 01 1F 99 81 6C C0 0D 9B 6F 76 00 `".H/....l...ov.
01A0: D3 CD 1D F9 89 F8 F9 F0 83 7D 34 3E F2 6C 08 41 ..........4>.l.A
01B0: F9 EA 1B 8D BC CF 7A 41 7B A0 89 F4 55 8E 09 94 ......zA....U...
01C0: AC FC 50 4B 99 E6 BA 21 04 CF 33 BD B5 2F B7 B0 ..PK...!..3../..
01D0: 06 38 59 89 8C 04 E8 4D C0 A4 D1 13 DD 47 25 4A .8Y....M.....G%J
01E0: 02 CE AC CA BE 75 C3 4A 30 A7 9C 84 0A 7E 1D 59 .....u.J0......Y
01F0: BA 2A AA 6C 58 C7 0C 7B BA 60 60 B3 77 E2 72 AE .*.lX....``.w.r.
]
Mar 02, 2020 8:35:28 PM se.magnuskkarlsson.example.bouncycastle.EncryptionUtils writePEM
INFO: Wrote /tmp/caCert-12617038054227389688.crt.pem