使用bouncy castle API在java中创建版本3,X.509证书层次结构

在本文中,我将讨论使用 bouncy castle API 在 java 程序中创建 SSL 证书。 Bouncy castle 是一种轻量级加密 API。它是 Java Cryptography Extension(JCE)和 Java Cryptography Architecture(JCA)的实现。

我将创建非常基本的证书,其中只包含必要的属性。您可以浏览 API 以获取可应用于证书的更多操作和属性

请在代码中导入以下依赖项。

<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on -->
     <dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcpkix-jdk15on</artifactId>
       <version>1.55</version>
     </dependency>
     <!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
     <dependency>
       <groupId>joda-time</groupId>
       <artifactId>joda-time</artifactId>
       <version>2.9.4</version>
     </dependency>
复制代码

我在代码中执行以下步骤: 步骤: 1)创建自签名根证书。 2)创建在步骤 1 中创建的根证书签名的中间证书. 3)创建在步骤 2 中创建的中间证书签名的最终用户证书。

代码:

 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.asn1.x509.BasicConstraints;
 import org.bouncycastle.asn1.x509.Extension;
 import org.bouncycastle.asn1.x509.KeyUsage;
 import org.bouncycastle.cert.X509v3CertificateBuilder;
 import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
 import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.bouncycastle.operator.OperatorCreationException;
 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import org.joda.time.DateTime;

 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
 import java.security.*;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Random;


 public class App {

   public static void main(String[] args) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, OperatorCreationException, InvalidKeyException, NoSuchProviderException, SignatureException, UnrecoverableKeyException {
     Security.addProvider(new BouncyCastleProvider());

     // Create self signed Root CA certificate
     KeyPair rootCAKeyPair = generateKeyPair();
     X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
         new X500Name("CN=rootCA"), // issuer authority
         BigInteger.valueOf(new Random().nextInt()), //serial number of certificate
         DateTime.now().toDate(), // start of validity
         new DateTime(2025, 12, 31, 0, 0, 0, 0).toDate(), //end of certificate validity
         new X500Name("CN=rootCA"), // subject name of certificate
         rootCAKeyPair.getPublic()); // public key of certificate
     // key usage restrictions
     builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign));
     builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true));
     X509Certificate rootCA = new JcaX509CertificateConverter().getCertificate(builder
         .build(new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").
             build(rootCAKeyPair.getPrivate()))); // private key of signing authority , here it is self signed
     saveToFile(rootCA, "D:\\rootCA.cer");


     //create Intermediate CA cert signed by Root CA
     KeyPair intermedCAKeyPair = generateKeyPair();
     builder = new JcaX509v3CertificateBuilder(
         rootCA, // here rootCA is issuer authority
         BigInteger.valueOf(new Random().nextInt()), DateTime.now().toDate(),
         new DateTime(2025, 12, 31, 0, 0, 0, 0).toDate(),
         new X500Name("CN=IntermedCA"), intermedCAKeyPair.getPublic());
     builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign));
     builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true));
     X509Certificate intermedCA = new JcaX509CertificateConverter().getCertificate(builder
         .build(new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").
             build(rootCAKeyPair.getPrivate())));// private key of signing authority , here it is signed by rootCA
     saveToFile(intermedCA, "D:\\intermedCA.cer");

     //create end user cert signed by Intermediate CA
     KeyPair endUserCertKeyPair = generateKeyPair();
     builder = new JcaX509v3CertificateBuilder(
         intermedCA, //here intermedCA is issuer authority
         BigInteger.valueOf(new Random().nextInt()), DateTime.now().toDate(),
         new DateTime(2025, 12, 31, 0, 0, 0, 0).toDate(),
         new X500Name("CN=endUserCert"), endUserCertKeyPair.getPublic());
     builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature));
     builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));
     X509Certificate endUserCert = new JcaX509CertificateConverter().getCertificate(builder
         .build(new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").
             build(intermedCAKeyPair.getPrivate())));// private key of signing authority , here it is signed by intermedCA
     saveToFile(endUserCert, "D:\\endUserCert.cer");
   }

   private static KeyPair generateKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException {
     KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");
     kpGen.initialize(2048, new SecureRandom());
     return kpGen.generateKeyPair();
   }

   private static void saveToFile(X509Certificate certificate, String filePath) throws IOException, CertificateEncodingException {
     FileOutputStream fileOutputStream = new FileOutputStream(filePath);
     fileOutputStream.write(certificate.getEncoded());
     fileOutputStream.flush();
     fileOutputStream.close();
   }

 }
复制代码

在这里你可以看到,对于 rootCA,我使用自己的私钥来签署证书。对于 intermedCA,我使用 rootCA 私钥进行签名。对于最终用户证书,我使用 IntermedCA 私钥进行签名。 在现实生活中,您还可以看到与此类似的证书链。从浏览器打开任何 HTTPS 连接证书,并观察证书链和每个证书的属性。

“SHA256withRSA”是我用它来签名证书的签名算法。 在 keyUsage 中,“keyCertSign”仅限制证书使用以签署其他证书。虽然 SSL 客户端需要“digitalSignature”使用,但我们的 Web 浏览器使用该证书进行实体身份验证和数据源身份验证的完整性。

BasicConstraints 中的“true”标志将证书标记为可以签署其他证书的 CA 证书。“false”标志将证书标记为证书链的最终实体。

作为此程序的出现,您将在指定的文件路径中拥有 3 个证书。

现在首先打开 rootCA:

您可以看到证书不可信的消息。因此,我们将此证书添加到受信任的根证书存储区中

1)单击“安装证书”按钮。 2)选择“本地计算机”,单击下一步 3)选择“将所有证书放在以下存储中”的第二个选项 4)浏览并选择“受信任的根证书颁发机构” 5)单击“下一步”,然后单击“完成”。 6)导入成功。

对于“Intermed CA”证书执行相同的操作,仅在步骤 4 中进行更改:浏览并选择“中间证书颁发机构”。

现在关闭证书并重新打开它。 让我们现在检查每个证书:

  1. RootCA

  1. 中间 CA

  1. 最终用户证书

还有其他方法可以创建证书和证书链。例如:java“keytool”命令或使用“keystore explorer”之类的工具.... 但很多时候你必须从程序中进行证书操作。 所以这在当时会非常有用。

在下一篇文章中,我将更多地介绍证书的主题以及您可以使用 java 程序中的 bouncy castle 执行的操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值