1
+ package com .ctrip .xpipe .redis .proxy .ssl ;
2
+
3
+ import java .io .FileOutputStream ;
4
+ import java .io .IOException ;
5
+ import java .math .BigInteger ;
6
+ import java .security .KeyPair ;
7
+ import java .security .KeyPairGenerator ;
8
+ import java .security .PrivateKey ;
9
+ import java .security .Security ;
10
+ import java .security .cert .X509Certificate ;
11
+ import java .util .Base64 ;
12
+ import java .util .Date ;
13
+
14
+ import org .bouncycastle .asn1 .x500 .X500Name ;
15
+ import org .bouncycastle .asn1 .x509 .BasicConstraints ;
16
+ import org .bouncycastle .asn1 .x509 .Extension ;
17
+ import org .bouncycastle .asn1 .x509 .KeyUsage ;
18
+ import org .bouncycastle .cert .X509v3CertificateBuilder ;
19
+ import org .bouncycastle .cert .jcajce .JcaX509CertificateConverter ;
20
+ import org .bouncycastle .cert .jcajce .JcaX509v3CertificateBuilder ;
21
+ import org .bouncycastle .jce .provider .BouncyCastleProvider ;
22
+ import org .bouncycastle .operator .ContentSigner ;
23
+ import org .bouncycastle .operator .jcajce .JcaContentSignerBuilder ;
24
+
25
+
26
+ public class GenerateCertificates {
27
+
28
+ private static boolean haLoaded = false ;
29
+
30
+ static {
31
+ Security .addProvider (new BouncyCastleProvider ());
32
+ }
33
+
34
+ public static void generateFile () throws Exception {
35
+
36
+ if (haLoaded ) {
37
+ return ;
38
+ }
39
+ haLoaded = true ;
40
+ // Generate CA key pair
41
+ KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance ("RSA" );
42
+ keyPairGen .initialize (2048 );
43
+ KeyPair caKeyPair = keyPairGen .generateKeyPair ();
44
+
45
+ // Generate CA certificate
46
+ X509Certificate caCert = generateCertificate ("CN=Test CA" , caKeyPair , 365 , "SHA256withRSA" , true );
47
+
48
+ // Generate client key pair
49
+ KeyPair clientKeyPair = keyPairGen .generateKeyPair ();
50
+
51
+ // Generate client certificate
52
+ X509Certificate clientCert = generateCertificate ("CN=Client" , clientKeyPair , 365 , "SHA256withRSA" , false , caCert , caKeyPair .getPrivate ());
53
+
54
+ // Generate server key pair
55
+ KeyPair serverKeyPair = keyPairGen .generateKeyPair ();
56
+
57
+ // Generate server certificate
58
+ X509Certificate serverCert = generateCertificate ("CN=Server" , serverKeyPair , 365 , "SHA256withRSA" , false , caCert , caKeyPair .getPrivate ());
59
+
60
+ // Write certificates to files
61
+ writePemFile ("CERTIFICATE" , "ca.crt" , caCert .getEncoded ());
62
+ writePemFile ("CERTIFICATE" , "client.crt" , clientCert .getEncoded ());
63
+ writePemFile ("CERTIFICATE" , "server.crt" , serverCert .getEncoded ());
64
+
65
+ // Write private keys to files
66
+ writePemFile ("PRIVATE KEY" , "pkcs8_client.key" , clientKeyPair .getPrivate ().getEncoded ());
67
+ writePemFile ("PRIVATE KEY" , "pkcs8_server.key" , serverKeyPair .getPrivate ().getEncoded ());
68
+
69
+ }
70
+
71
+ private static X509Certificate generateCertificate (String dn , KeyPair pair , int days , String algorithm , boolean isCA ) throws Exception {
72
+ return generateCertificate (dn , pair , days , algorithm , isCA , null , null );
73
+ }
74
+
75
+ private static X509Certificate generateCertificate (String dn , KeyPair pair , int days , String algorithm , boolean isCA , X509Certificate issuerCert , PrivateKey issuerKey ) throws Exception {
76
+ X500Name issuer = issuerCert == null ? new X500Name (dn ) : new X500Name (issuerCert .getSubjectX500Principal ().getName ());
77
+ X500Name subject = new X500Name (dn );
78
+ BigInteger serial = BigInteger .valueOf (System .currentTimeMillis ());
79
+ Date notBefore = new Date ();
80
+ Date notAfter = new Date (notBefore .getTime () + days * 86400000L );
81
+
82
+ X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder (
83
+ issuer , serial , notBefore , notAfter , subject , pair .getPublic ()
84
+ );
85
+
86
+ certBuilder .addExtension (Extension .basicConstraints , true , new BasicConstraints (isCA ));
87
+ certBuilder .addExtension (Extension .keyUsage , true , new KeyUsage (KeyUsage .keyCertSign | KeyUsage .digitalSignature ));
88
+
89
+ ContentSigner signer = new JcaContentSignerBuilder (algorithm ).build (issuerKey == null ? pair .getPrivate () : issuerKey );
90
+ return new JcaX509CertificateConverter ().setProvider (BouncyCastleProvider .PROVIDER_NAME ).getCertificate (certBuilder .build (signer ));
91
+ }
92
+
93
+ private static void writePemFile (String type , String filename , byte [] encoded ) throws IOException {
94
+ Base64 .Encoder encoder = Base64 .getMimeEncoder (64 , new byte [] { '\n' });
95
+ String certDir = System .getProperty ("java.io.tmpdir" );
96
+ try (FileOutputStream fos = new FileOutputStream (certDir + "/" + filename )) {
97
+ fos .write (("-----BEGIN " + type + "-----\n " ).getBytes ());
98
+ fos .write (encoder .encode (encoded ));
99
+ fos .write (("\n -----END " + type + "-----\n " ).getBytes ());
100
+ }
101
+ }
102
+
103
+ }
0 commit comments