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