-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathKeystoreAndKeysTest.java
More file actions
188 lines (151 loc) · 9.17 KB
/
KeystoreAndKeysTest.java
File metadata and controls
188 lines (151 loc) · 9.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package com.here.had.webapps.crypto;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
import org.bouncycastle.util.encoders.Base64;
import org.junit.Test;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
public class KeystoreAndKeysTest {
private static final String BC_PROVIDER = "BC";
private static final String KEY_ALGORITHM = "RSA";
private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
@Test
public void generateSymmetricalKey() throws NoSuchAlgorithmException {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // for example
SecretKey secretKey = keyGen.generateKey();
System.out.println(secretKey);
}
@Test
public void generatingKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
System.out.println(keyPair.getPublic());
System.out.println(keyPair.getPrivate());
}
@Test
public void loadKeystore() throws Exception {
KeyStore keyStore = KeyStore.getInstance("pkcs12");
InputStream is = this.getClass().getResourceAsStream("/vivek.pfx");
keyStore.load(is, "password".toCharArray());
Certificate certificate = keyStore.getCertificate("Vivek");
System.out.println(certificate);
}
@Test
public void loadWindowsKeystore() throws Exception {
KeyStore keyStore = KeyStore.getInstance("windows-root");
keyStore.load(null);
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
System.out.println(aliases.nextElement());
}
}
@Test
public void generateKeystore() throws Exception {
Security.addProvider(new BouncyCastleProvider());
// Initialize a new KeyPair generator
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM, BC_PROVIDER);
keyPairGenerator.initialize(2048);
// Setup start date to yesterday and end date for 1 year validity
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -1);
Date startDate = calendar.getTime();
calendar.add(Calendar.YEAR, 1);
Date endDate = calendar.getTime();
// First step is to create a root certificate
// First Generate a KeyPair,
// then a random serial number
// then generate a certificate using the KeyPair
KeyPair rootKeyPair = keyPairGenerator.generateKeyPair();
BigInteger rootSerialNum = new BigInteger(Long.toString(new SecureRandom().nextLong()));
// Issued By and Issued To same for root certificate
org.bouncycastle.asn1.x500.X500Name rootCertIssuer = new org.bouncycastle.asn1.x500.X500Name("CN=root-cert");
org.bouncycastle.asn1.x500.X500Name rootCertSubject = rootCertIssuer;
ContentSigner rootCertContentSigner = new JcaContentSignerBuilder(SIGNATURE_ALGORITHM).setProvider(BC_PROVIDER).build(rootKeyPair.getPrivate());
X509v3CertificateBuilder rootCertBuilder = new JcaX509v3CertificateBuilder(rootCertIssuer, rootSerialNum, startDate, endDate, rootCertSubject, rootKeyPair.getPublic());
// Add Extensions
// A BasicConstraint to mark root certificate as CA certificate
JcaX509ExtensionUtils rootCertExtUtils = new JcaX509ExtensionUtils();
rootCertBuilder.addExtension(Extension.basicConstraints, true, new BasicConstraints(true));
rootCertBuilder.addExtension(Extension.subjectKeyIdentifier, false, rootCertExtUtils.createSubjectKeyIdentifier(rootKeyPair.getPublic()));
// Create a cert holder and export to X509Certificate
X509CertificateHolder rootCertHolder = rootCertBuilder.build(rootCertContentSigner);
X509Certificate rootCert = new JcaX509CertificateConverter().setProvider(BC_PROVIDER).getCertificate(rootCertHolder);
writeCertToFileBase64Encoded(rootCert, "root-cert.cer");
exportKeyPairToKeystoreFile(rootKeyPair, rootCert, "root-cert", "root-cert.pfx", "PKCS12", "pass");
// Generate a new KeyPair and sign it using the Root Cert Private Key
// by generating a CSR (Certificate Signing Request)
org.bouncycastle.asn1.x500.X500Name issuedCertSubject = new X500Name("CN=issued-cert");
BigInteger issuedCertSerialNum = new BigInteger(Long.toString(new SecureRandom().nextLong()));
KeyPair issuedCertKeyPair = keyPairGenerator.generateKeyPair();
PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(issuedCertSubject, issuedCertKeyPair.getPublic());
JcaContentSignerBuilder csrBuilder = new JcaContentSignerBuilder(SIGNATURE_ALGORITHM).setProvider(BC_PROVIDER);
// Sign the new KeyPair with the root cert Private Key
ContentSigner csrContentSigner = csrBuilder.build(rootKeyPair.getPrivate());
PKCS10CertificationRequest csr = p10Builder.build(csrContentSigner);
// Use the Signed KeyPair and CSR to generate an issued Certificate
// Here serial number is randomly generated. In general, CAs use
// a sequence to generate Serial number and avoid collisions
X509v3CertificateBuilder issuedCertBuilder = new X509v3CertificateBuilder(rootCertIssuer, issuedCertSerialNum, startDate, endDate, csr.getSubject(), csr.getSubjectPublicKeyInfo());
JcaX509ExtensionUtils issuedCertExtUtils = new JcaX509ExtensionUtils();
// Add Extensions
// Use BasicConstraints to say that this Cert is not a CA
issuedCertBuilder.addExtension(Extension.basicConstraints, true, new BasicConstraints(false));
// Add Issuer cert identifier as Extension
issuedCertBuilder.addExtension(Extension.authorityKeyIdentifier, false, issuedCertExtUtils.createAuthorityKeyIdentifier(rootCert));
issuedCertBuilder.addExtension(Extension.subjectKeyIdentifier, false, issuedCertExtUtils.createSubjectKeyIdentifier(csr.getSubjectPublicKeyInfo()));
// Add intended key usage extension if needed
issuedCertBuilder.addExtension(Extension.keyUsage, false, new KeyUsage(KeyUsage.keyEncipherment));
// Add DNS name is cert is to used for SSL
issuedCertBuilder.addExtension(Extension.subjectAlternativeName, false, new DERSequence(new ASN1Encodable[] {
new GeneralName(GeneralName.dNSName, "mydomain.local"),
new GeneralName(GeneralName.iPAddress, "127.0.0.1")
}));
X509CertificateHolder issuedCertHolder = issuedCertBuilder.build(csrContentSigner);
X509Certificate issuedCert = new JcaX509CertificateConverter().setProvider(BC_PROVIDER).getCertificate(issuedCertHolder);
// Verify the issued cert signature against the root (issuer) cert
issuedCert.verify(rootCert.getPublicKey(), BC_PROVIDER);
writeCertToFileBase64Encoded(issuedCert, "issued-cert.cer");
exportKeyPairToKeystoreFile(issuedCertKeyPair, issuedCert, "issued-cert", "issued-cert.pfx", "PKCS12", "pass");
}
static void exportKeyPairToKeystoreFile(KeyPair keyPair, Certificate certificate, String alias, String fileName, String storeType, String storePass) throws Exception {
KeyStore sslKeyStore = KeyStore.getInstance(storeType, BC_PROVIDER);
sslKeyStore.load(null, null);
sslKeyStore.setKeyEntry(alias, keyPair.getPrivate(),null, new Certificate[]{certificate});
FileOutputStream keyStoreOs = new FileOutputStream(fileName);
sslKeyStore.store(keyStoreOs, storePass.toCharArray());
}
static void writeCertToFileBase64Encoded(Certificate certificate, String fileName) throws Exception {
FileOutputStream certificateOut = new FileOutputStream(fileName);
certificateOut.write("-----BEGIN CERTIFICATE-----".getBytes());
certificateOut.write(Base64.encode(certificate.getEncoded()));
certificateOut.write("-----END CERTIFICATE-----".getBytes());
certificateOut.close();
}
}