Generate certificate in Java -- Certificate chain

In previous post, we have introduced the use of Certificate and how to generate self signed certificate using Java. In this post, we will show you how to generate a certificate chain. Sometimes we may only have a certificate request or we don't have a trusted certificate which can be used for business. Now we need to have a trusted CA to sign our certificate so that it can be used on SSL communications.

To generate a certificate chain, we may first have our own certificate(A), then we may use other certificate(B) and its associated private key to sign the certificate we have, then we will use another certificate(C) and its associated private key to sign certificate B...this process will continue until you have a trusted root certificate to sign the previous certificate. Then you have a certificate chain. This trusted root CA may be from VeriSign or other CAs.

In Java, we can use below codes to create certificate chain.

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
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
 
import javax.security.cert.Certificate;
 
import sun.security.x509.BasicConstraintsExtension;
import sun.security.x509.CertAndKeyGen;
import sun.security.x509.CertificateExtensions;
import sun.security.x509.CertificateIssuerName;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
 
public class CertificateChainGeneration {
     public static void main(String[] args){
         try {
             //Generate ROOT certificate
             CertAndKeyGen keyGen= new CertAndKeyGen( "RSA" , "SHA1WithRSA" , null );
             keyGen.generate( 1024 );
             PrivateKey rootPrivateKey=keyGen.getPrivateKey();
             
             X509Certificate rootCertificate = keyGen.getSelfCertificate( new X500Name( "CN=ROOT" ), ( long ) 365 * 24 * 60 * 60 );
             
             //Generate intermediate certificate
             CertAndKeyGen keyGen1= new CertAndKeyGen( "RSA" , "SHA1WithRSA" , null );
             keyGen1.generate( 1024 );
             PrivateKey middlePrivateKey=keyGen1.getPrivateKey();
             
             X509Certificate middleCertificate = keyGen1.getSelfCertificate( new X500Name( "CN=MIDDLE" ), ( long ) 365 * 24 * 60 * 60 );
             
             //Generate leaf certificate
             CertAndKeyGen keyGen2= new CertAndKeyGen( "RSA" , "SHA1WithRSA" , null );
             keyGen2.generate( 1024 );
             PrivateKey topPrivateKey=keyGen2.getPrivateKey();
             
             X509Certificate topCertificate = keyGen2.getSelfCertificate( new X500Name( "CN=TOP" ), ( long ) 365 * 24 * 60 * 60 );
             
             rootCertificate   = createSignedCertificate(rootCertificate,rootCertificate,rootPrivateKey);
             middleCertificate = createSignedCertificate(middleCertificate,rootCertificate,rootPrivateKey);
             topCertificate    = createSignedCertificate(topCertificate,middleCertificate,middlePrivateKey);
             
             X509Certificate[] chain = new X509Certificate[ 3 ];
             chain[ 0 ]=topCertificate;
             chain[ 1 ]=middleCertificate;
             chain[ 2 ]=rootCertificate;  
         } catch (Exception ex){
             ex.printStackTrace();
         }
     }
     
     private static X509Certificate createSignedCertificate(X509Certificate cetrificate,X509Certificate issuerCertificate,PrivateKey issuerPrivateKey){
         try {
             Principal issuer = issuerCertificate.getSubjectDN();
             String issuerSigAlg = issuerCertificate.getSigAlgName();
             
             byte [] inCertBytes = cetrificate.getTBSCertificate();
             X509CertInfo info = new X509CertInfo(inCertBytes);
             info.set(X509CertInfo.ISSUER, new CertificateIssuerName((X500Name) issuer));
             
             //No need to add the BasicContraint for leaf cert
             if (!cetrificate.getSubjectDN().getName().equals( "CN=TOP" )){
                 CertificateExtensions exts= new CertificateExtensions();
                 BasicConstraintsExtension bce = new BasicConstraintsExtension( true , - 1 );
                 exts.set(BasicConstraintsExtension.NAME, new BasicConstraintsExtension( false , bce.getExtensionValue()));
                 info.set(X509CertInfo.EXTENSIONS, exts);
             }
             
             X509CertImpl outCert = new X509CertImpl(info);
             outCert.sign(issuerPrivateKey, issuerSigAlg);
             
             return outCert;
         } catch (Exception ex){
             ex.printStackTrace();
         }
         return null ;
     }
}

Here we first create three self signed certificates and their associated private keys. Then we use one certificate and its private key to sign another certificate.

Note that the certificate except the leaf cert in a workable certificate chain should contain an CA extension to indicate the certificate is a CA certificate. So you will see that we will add CA extension to the certificate when we sign a certificate in createSignedCertificate().

In next post, we will show you how to store the certificate and keys into different types of keystores such as JKS, PKCS12

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值