View Javadoc
1   package org.argeo.cms.internal.kernel;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.FileOutputStream;
6   import java.math.BigInteger;
7   import java.security.KeyPair;
8   import java.security.KeyPairGenerator;
9   import java.security.KeyStore;
10  import java.security.SecureRandom;
11  import java.security.Security;
12  import java.security.cert.Certificate;
13  import java.security.cert.X509Certificate;
14  import java.util.Date;
15  
16  import javax.security.auth.x500.X500Principal;
17  
18  import org.argeo.cms.CmsException;
19  import org.bouncycastle.cert.X509v3CertificateBuilder;
20  import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
21  import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
22  import org.bouncycastle.jce.provider.BouncyCastleProvider;
23  import org.bouncycastle.operator.ContentSigner;
24  import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
25  
26  /**
27   * Utilities around private keys and certificate, mostly wrapping BouncyCastle
28   * implementations.
29   */
30  class PkiUtils {
31  	final static String PKCS12 = "PKCS12";
32  
33  	private final static String SECURITY_PROVIDER;
34  	static {
35  		Security.addProvider(new BouncyCastleProvider());
36  		SECURITY_PROVIDER = "BC";
37  	}
38  
39  	public static X509Certificate generateSelfSignedCertificate(KeyStore keyStore, X500Principal x500Principal,
40  			int keySize, char[] keyPassword) {
41  		try {
42  			KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", SECURITY_PROVIDER);
43  			kpGen.initialize(keySize, new SecureRandom());
44  			KeyPair pair = kpGen.generateKeyPair();
45  			Date notBefore = new Date(System.currentTimeMillis() - 10000);
46  			Date notAfter = new Date(System.currentTimeMillis() + 365 * 24L * 3600 * 1000);
47  			BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());
48  			X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(x500Principal, serial, notBefore,
49  					notAfter, x500Principal, pair.getPublic());
50  			ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(SECURITY_PROVIDER)
51  					.build(pair.getPrivate());
52  			X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
53  					.getCertificate(certGen.build(sigGen));
54  			cert.checkValidity(new Date());
55  			cert.verify(cert.getPublicKey());
56  
57  			keyStore.setKeyEntry(x500Principal.getName(), pair.getPrivate(), keyPassword, new Certificate[] { cert });
58  			return cert;
59  		} catch (Exception e) {
60  			throw new CmsException("Cannot generate self-signed certificate", e);
61  		}
62  	}
63  
64  	public static KeyStore getKeyStore(File keyStoreFile, char[] keyStorePassword, String keyStoreType) {
65  		try {
66  			KeyStore store = KeyStore.getInstance(keyStoreType, SECURITY_PROVIDER);
67  			if (keyStoreFile.exists()) {
68  				try (FileInputStream fis = new FileInputStream(keyStoreFile)) {
69  					store.load(fis, keyStorePassword);
70  				}
71  			} else {
72  				store.load(null);
73  			}
74  			return store;
75  		} catch (Exception e) {
76  			throw new CmsException("Cannot load keystore " + keyStoreFile, e);
77  		}
78  	}
79  
80  	public static void saveKeyStore(File keyStoreFile, char[] keyStorePassword, KeyStore keyStore) {
81  		try {
82  			try (FileOutputStream fis = new FileOutputStream(keyStoreFile)) {
83  				keyStore.store(fis, keyStorePassword);
84  			}
85  		} catch (Exception e) {
86  			throw new CmsException("Cannot save keystore " + keyStoreFile, e);
87  		}
88  	}
89  
90  	public static void main(String[] args) {
91  		final String ALGORITHM = "RSA";
92  		final String provider = "BC";
93  		SecureRandom secureRandom = new SecureRandom();
94  		long begin = System.currentTimeMillis();
95  		for (int i = 512; i < 1024; i = i + 2) {
96  			try {
97  				KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM, provider);
98  				keyGen.initialize(i, secureRandom);
99  				keyGen.generateKeyPair();
100 			} catch (Exception e) {
101 				System.err.println(i + " : " + e.getMessage());
102 			}
103 		}
104 		System.out.println((System.currentTimeMillis() - begin) + " ms");
105 
106 		// // String text = "a";
107 		// String text =
108 		// "testtesttesttesttesttesttesttesttesttesttesttesttesttesttest";
109 		// try {
110 		// System.out.println(text);
111 		// PrivateKey privateKey;
112 		// PublicKey publicKey;
113 		// char[] password = "changeit".toCharArray();
114 		// String alias = "CN=test";
115 		// KeyStore keyStore = KeyStore.getInstance("pkcs12");
116 		// File p12file = new File("test.p12");
117 		// p12file.delete();
118 		// if (!p12file.exists()) {
119 		// keyStore.load(null);
120 		// generateSelfSignedCertificate(keyStore, new X500Principal(alias),
121 		// 513, password);
122 		// try (OutputStream out = new FileOutputStream(p12file)) {
123 		// keyStore.store(out, password);
124 		// }
125 		// }
126 		// try (InputStream in = new FileInputStream(p12file)) {
127 		// keyStore.load(in, password);
128 		// privateKey = (PrivateKey) keyStore.getKey(alias, password);
129 		// publicKey = keyStore.getCertificateChain(alias)[0].getPublicKey();
130 		// }
131 		// // KeyPair key;
132 		// // final KeyPairGenerator keyGen =
133 		// // KeyPairGenerator.getInstance(ALGORITHM);
134 		// // keyGen.initialize(4096, new SecureRandom());
135 		// // long begin = System.currentTimeMillis();
136 		// // key = keyGen.generateKeyPair();
137 		// // System.out.println((System.currentTimeMillis() - begin) + " ms");
138 		// // keyStore.load(null);
139 		// // keyStore.setKeyEntry("test", key.getPrivate(), password, null);
140 		// // try(OutputStream out=new FileOutputStream(p12file)) {
141 		// // keyStore.store(out, password);
142 		// // }
143 		// // privateKey = key.getPrivate();
144 		// // publicKey = key.getPublic();
145 		//
146 		// Cipher encrypt = Cipher.getInstance(ALGORITHM);
147 		// encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
148 		// byte[] encrypted = encrypt.doFinal(text.getBytes());
149 		// String encryptedBase64 =
150 		// Base64.getEncoder().encodeToString(encrypted);
151 		// System.out.println(encryptedBase64);
152 		// byte[] encryptedFromBase64 =
153 		// Base64.getDecoder().decode(encryptedBase64);
154 		//
155 		// Cipher decrypt = Cipher.getInstance(ALGORITHM);
156 		// decrypt.init(Cipher.DECRYPT_MODE, privateKey);
157 		// byte[] decrypted = decrypt.doFinal(encryptedFromBase64);
158 		// System.out.println(new String(decrypted));
159 		// } catch (Exception e) {
160 		// e.printStackTrace();
161 		// }
162 
163 	}
164 
165 }