Net8 使用BouncyCastle 生成自簽名證書

扫地僧2015發表於2024-03-13
 private AsymmetricCipherKeyPair GenerateKeyPair()
 {
     var generator = new RsaKeyPairGenerator();
     generator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));

     return generator.GenerateKeyPair();
 }

 private X509Certificate GenerateRootCertificate(AsymmetricCipherKeyPair keyPair, string subject, string[] ipAddresses)
 {

     Asn1SignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WithRSA", keyPair.Private, null);
     var certGenerator = new X509V3CertificateGenerator();
     certGenerator.SetSerialNumber(BigInteger.ValueOf(DateTime.Now.Ticks));
     certGenerator.SetIssuerDN(new X509Name(subject));
     certGenerator.SetSubjectDN(new X509Name(subject));
     certGenerator.SetNotBefore(DateTime.UtcNow);
     certGenerator.SetNotAfter(DateTime.UtcNow.AddYears(1));

     List<Asn1Encodable> asn1Encodables = new List<Asn1Encodable>();
     foreach (var ipAddress in ipAddresses)
     {
         asn1Encodables.Add(new GeneralName(GeneralName.IPAddress, ipAddress));
     }
     certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector([.. asn1Encodables])));
     certGenerator.SetPublicKey(keyPair.Public);
     var cert = certGenerator.Generate(signatureFactory);
     return cert;
 }

 private X509Certificate GenerateCertificate(AsymmetricCipherKeyPair keyPair, X509Certificate issuerCert, AsymmetricKeyParameter issuerKey, string subject, string[] ipAddresses)
 {
     Asn1SignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WithRSA", issuerKey, null);
     var certGenerator = new X509V3CertificateGenerator();
     certGenerator.SetSerialNumber(BigInteger.ValueOf(DateTime.Now.Ticks));
     certGenerator.SetIssuerDN(issuerCert.SubjectDN);
     certGenerator.SetSubjectDN(new X509Name(subject));
     certGenerator.SetNotBefore(DateTime.UtcNow);
     certGenerator.SetNotAfter(DateTime.UtcNow.AddYears(1));
     certGenerator.SetPublicKey(keyPair.Public);
     List<Asn1Encodable> asn1Encodables = new List<Asn1Encodable>();
     foreach (var ipAddress in ipAddresses)
     {
         asn1Encodables.Add(new GeneralName(GeneralName.IPAddress, ipAddress));
     }
     certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector([.. asn1Encodables])));
     var cert = certGenerator.Generate(signatureFactory);
     return cert;
 }

 private void SaveToPem(string certFileName, string keyFileName, X509Certificate cert, AsymmetricKeyParameter key)
 {
     // 儲存證書
     using (TextWriter certTW = File.CreateText(certFileName))
     {
         PemWriter certPemWriter = new PemWriter(certTW);
         certPemWriter.WriteObject(cert);
         certPemWriter.Writer.Flush();
     }

     // 儲存私鑰
     using (TextWriter keyTW = File.CreateText(keyFileName))
     {
         PemWriter keyPemWriter = new PemWriter(keyTW);
         keyPemWriter.WriteObject(key);
         keyPemWriter.Writer.Flush();
     }
 }


 public static void ExportCertificateToPfx(X509Certificate2 certificate, string fileName, string password)
 {
     File.WriteAllBytes(fileName, certificate.Export(X509ContentType.Pfx, password));
 }

 public X509Certificate LoadBouncyCastleCertificate(string certFilePath)
 {
     // 讀取Bouncy Castle生成的證書檔案
     X509CertificateParser parser = new X509CertificateParser();
     X509Certificate bcCert = parser.ReadCertificate(File.ReadAllBytes(certFilePath));
     return bcCert;
 }


  public void GenerateCertificates()
  {
      string[] ipAddresses = { "192.168.0.101", "10.0.0.1" };

      // 生成根證書
      AsymmetricCipherKeyPair rootKeyPair = GenerateKeyPair();
      X509Certificate rootCert = GenerateRootCertificate(rootKeyPair, "CN=Root CA", ipAddresses);

      // 生成客戶端證書
      AsymmetricCipherKeyPair clientKeyPair = GenerateKeyPair();
      X509Certificate clientCert = GenerateCertificate(clientKeyPair, rootCert, rootKeyPair.Private, "CN=Client", ipAddresses);

      // 生成服務端證書
      AsymmetricCipherKeyPair serverKeyPair = GenerateKeyPair();
      X509Certificate serverCert = GenerateCertificate(serverKeyPair, rootCert, rootKeyPair.Private, "CN=Server", ipAddresses);


      // 將證書和私鑰儲存為PEM格式的檔案
      // 將證書和私鑰分別儲存為PEM格式的檔案
      SaveToPem("bouncyCastle/ca.crt", "bouncyCastle/ca.key", rootCert, rootKeyPair.Private);
      SaveToPem("bouncyCastle/client.crt", "bouncyCastle/client.key", clientCert, clientKeyPair.Private);
      SaveToPem("bouncyCastle/server.crt", "bouncyCastle/server.key", serverCert, serverKeyPair.Private);


      // Convert to X509Certificate2 format
      X509Certificate2 certRoot = new X509Certificate2(rootCert.GetEncoded());
      ExportCertificateToPfx(certRoot, "bouncyCastle/ca.pfx", "123456");

      X509Certificate2 certServer = new X509Certificate2(serverCert.GetEncoded());
      ExportCertificateToPfx(certServer, "bouncyCastle/server.pfx", "123456");

      X509Certificate2 certClient = new X509Certificate2(clientCert.GetEncoded());
      ExportCertificateToPfx(certClient, "bouncyCastle/client.pfx", "123456");
  }

  原始碼地址 https://github.com/zhenglong2015/CAManager

相關文章