diff --git a/FastGithub.ReverseProxy/CertGenerator.cs b/FastGithub.ReverseProxy/CertGenerator.cs index 2ca6ee4..a1ca06f 100644 --- a/FastGithub.ReverseProxy/CertGenerator.cs +++ b/FastGithub.ReverseProxy/CertGenerator.cs @@ -29,6 +29,31 @@ namespace FastGithub.ReverseProxy { private static readonly SecureRandom secureRandom = new(); + /// + /// 生成自签名证书 + /// + /// + /// + /// + /// + /// + /// + public static void GenerateBySelf(IEnumerable domains, int keySizeBits, DateTime validFrom, DateTime validTo, string caPublicCerPath, string caPrivateKeyPath) + { + var keys = GenerateRsaKeyPair(keySizeBits); + var cert = GenerateCertificate(domains, keys.Public, validFrom, validTo, domains.First(), null, keys.Private, null); + + using var priWriter = new StreamWriter(caPrivateKeyPath); + var priPemWriter = new PemWriter(priWriter); + priPemWriter.WriteObject(keys.Private); + priPemWriter.Writer.Flush(); + + using var pubWriter = new StreamWriter(caPublicCerPath); + var pubPemWriter = new PemWriter(pubWriter); + pubPemWriter.WriteObject(cert); + pubPemWriter.Writer.Flush(); + } + /// /// 生成CA签名证书 /// @@ -39,7 +64,7 @@ namespace FastGithub.ReverseProxy /// /// /// - public static X509Certificate2 Generate(IEnumerable domains, int keySizeBits, DateTime validFrom, DateTime validTo, string caPublicCerPath, string caPrivateKeyPath, string? password = default) + public static X509Certificate2 GenerateByCa(IEnumerable domains, int keySizeBits, DateTime validFrom, DateTime validTo, string caPublicCerPath, string caPrivateKeyPath, string? password = default) { if (File.Exists(caPublicCerPath) == false) { @@ -90,7 +115,7 @@ namespace FastGithub.ReverseProxy /// /// /// - private static X509Certificate GenerateCertificate(IEnumerable domains, AsymmetricKeyParameter subjectPublic, DateTime validFrom, DateTime validTo, string issuerName, AsymmetricKeyParameter issuerPublic, AsymmetricKeyParameter issuerPrivate, int? CA_PathLengthConstraint) + private static X509Certificate GenerateCertificate(IEnumerable domains, AsymmetricKeyParameter subjectPublic, DateTime validFrom, DateTime validTo, string issuerName, AsymmetricKeyParameter? issuerPublic, AsymmetricKeyParameter issuerPrivate, int? CA_PathLengthConstraint) { var signatureFactory = issuerPrivate is ECPrivateKeyParameters ? new Asn1SignatureFactory(X9ObjectIdentifiers.ECDsaWithSha256.ToString(), issuerPrivate) diff --git a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs index 8fa4da0..68c060a 100644 --- a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs +++ b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net; using System.Net.NetworkInformation; @@ -35,7 +36,9 @@ namespace FastGithub { var loggerFactory = kestrel.ApplicationServices.GetRequiredService(); var logger = loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(ReverseProxy)}"); - TryInstallCaCert(caPublicCerPath, logger); + + GeneratorCaCert(caPublicCerPath, caPrivateKeyPath); + InstallCaCert(caPublicCerPath, logger); kestrel.ListenAnyIP(443, listen => listen.UseHttps(https => @@ -45,6 +48,51 @@ namespace FastGithub logger.LogInformation("https反向代理服务启动成功"); } + /// + /// 生成根证书 + /// + /// + /// + private static void GeneratorCaCert(string caPublicCerPath, string caPrivateKeyPath) + { + if (File.Exists(caPublicCerPath) && File.Exists(caPublicCerPath)) + { + return; + } + + File.Delete(caPublicCerPath); + File.Delete(caPrivateKeyPath); + + var validFrom = DateTime.Today.AddYears(-10); + var validTo = DateTime.Today.AddYears(50); + CertGenerator.GenerateBySelf(new[] { nameof(FastGithub) }, 2048, validFrom, validTo, caPublicCerPath, caPrivateKeyPath); + } + + + /// + /// 安装根证书 + /// + /// + /// + private static void InstallCaCert(string caPublicCerPath, ILogger logger) + { + try + { + var caCert = new X509Certificate2(caPublicCerPath); + using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); + store.Open(OpenFlags.ReadWrite); + if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0) + { + store.Add(caCert); + store.Close(); + } + } + catch (Exception) + { + logger.LogWarning($"安装根证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”"); + } + } + /// /// 获取颁发给指定域名的证书 /// @@ -63,7 +111,7 @@ namespace FastGithub var domains = GetDomains(host).Distinct(); var validFrom = DateTime.Today.AddYears(-1); var validTo = DateTime.Today.AddYears(10); - return CertGenerator.Generate(domains, 2048, validFrom, validTo, caPublicCerPath, caPrivateKeyPath); + return CertGenerator.GenerateByCa(domains, 2048, validFrom, validTo, caPublicCerPath, caPrivateKeyPath); }, LazyThreadSafetyMode.ExecutionAndPublication); } } @@ -94,29 +142,5 @@ namespace FastGithub } } } - - /// - /// 安装根证书 - /// - /// - /// - private static void TryInstallCaCert(string caPublicCerPath, ILogger logger) - { - try - { - var caCert = new X509Certificate2(caPublicCerPath); - using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); - store.Open(OpenFlags.ReadWrite); - if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0) - { - store.Add(caCert); - store.Close(); - } - } - catch (Exception) - { - logger.LogWarning($"安装根证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”"); - } - } } } diff --git a/FastGithub/FastGithub.cer b/FastGithub/FastGithub.cer deleted file mode 100644 index 57b2275..0000000 --- a/FastGithub/FastGithub.cer +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC2DCCAcCgAwIBAgIQAKaUqwPmF9dDFtqNp34mRTANBgkqhkiG9w0BAQsFADAY -MRYwFAYDVQQDDA1GYXN0R2l0aHViX0NBMCAXDTExMDcxMzAwMDAwMFoYDzI1MjEw -NzEzMDAwMDAwWjAYMRYwFAYDVQQDDA1GYXN0R2l0aHViX0NBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1vNFkTGacoKdOY+H8Va7BN/z+nXyUHI1aZGC -11uzRVggi7EDxL2ThufzrQNEMqmh7aI6UbmnFMee+UtzexBSl2x8sH0uOPL31Pbh -fsrrgjMW0p8doApaTlEVyrXI5SVEapf+B13y/Nu6e2PQ4gRT4WZaBfLgqQdcaT9/ -RdaexznlRYzet6HAKf/Hvs5tkbWkLY9mvctcMWm998wjVVD2vTyZ7Pe7s7L2w/fG -mcz0svonr18zI+kHK/hK/2u/jvnmC8HpvhnDbNp7brOvR0TF6oYjKB20Zicy32UK -0/PekVN9T8dzOwjkZXJ0xI7RRVLOLG1qkO8z8BhyznjQLLZSLwIDAQABoxwwGjAY -BgNVHREEETAPgg1GYXN0R2l0aHViX0NBMA0GCSqGSIb3DQEBCwUAA4IBAQCYR68q -oKqBiNKlWgaaY8o2w7PGL0NZ2QVGlZp4Yl8Jj60qx587TSN9YTjMgNpZnkCYJZbQ -AhJAcwVspFsAq90SG/md0A6o3TRHSEV2HJIvAoMTiT/LLG+ZU61/NxMl0WxoQPKz -OcleOo+fCklove9jYIhHsls30eQv/NGn+pKhnCI9VEC+sUxbxQd4LJQbBYouNV6I -Sd8axEazqWsQrfX+CvNb2UjH3aaARaPWcacTcVlO5XJz2eDnUzVQOWwgv57sLUmY -xn0HbGp4lATgNeUSBcn7pEHv/yjqraJn2cVl0l/ZaFcYcccYZFrA3qAi14aiGRtu -SSC6OWHrtXwXZnkn ------END CERTIFICATE----- diff --git a/FastGithub/FastGithub.csproj b/FastGithub/FastGithub.csproj index f28bfe4..a097389 100644 --- a/FastGithub/FastGithub.csproj +++ b/FastGithub/FastGithub.csproj @@ -35,9 +35,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest diff --git a/FastGithub/FastGithub.key b/FastGithub/FastGithub.key deleted file mode 100644 index 1758c6d..0000000 --- a/FastGithub/FastGithub.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA1vNFkTGacoKdOY+H8Va7BN/z+nXyUHI1aZGC11uzRVggi7ED -xL2ThufzrQNEMqmh7aI6UbmnFMee+UtzexBSl2x8sH0uOPL31PbhfsrrgjMW0p8d -oApaTlEVyrXI5SVEapf+B13y/Nu6e2PQ4gRT4WZaBfLgqQdcaT9/RdaexznlRYze -t6HAKf/Hvs5tkbWkLY9mvctcMWm998wjVVD2vTyZ7Pe7s7L2w/fGmcz0svonr18z -I+kHK/hK/2u/jvnmC8HpvhnDbNp7brOvR0TF6oYjKB20Zicy32UK0/PekVN9T8dz -OwjkZXJ0xI7RRVLOLG1qkO8z8BhyznjQLLZSLwIDAQABAoIBABamHILviJgfRiTO -CGN4IY2icWlHK0ipuBIPGIvLqEiawBcoCD8fQJ+66hSlXva9pAfPi7iXyNCqNgiL -mDfz4Nf+wOax0gCDLXT9rIX5KLaX3oRD6tG1tY1CAvtQi0IF2r8mk8g/8H4PQweE -XXqrPRFngP3WeTCmS2j1nVoFAsb4E7ZOKVVD3z6wILWHUfXuAeV/R1/pqbDvc4Yn -i2+PZvHZVjftkOqy7FyNE18y2Q198TKWATV1WzrB/Tv0mVoQN/izM9HflERUvvMo -v+I9ZTKrLgnHo5bHprVLRQnHfBJo/SDHJTCtP57sGElUaYl9nFM6k47k0Jp71zID -2UrlY/kCgYEA+ZFD2L+q6y4nDXOngDUiRiLbRJDb2u5pOY6scRHa73KCvq+t+Bih -fxtE9h4EDa1zei/tR6gkQnoIe9Nviikz2YyTrZkqHzAK55who9H6GT9pErNUvXF2 -dnje2KlRcjniMp8vcm1sbYMDEt+NFS2sL8rby97bZQ+V5WjLoYAhAacCgYEA3H2X -IPDudA6cFPczn+19qw76nKdrc3LkxToYdscb/8tH6dX+yrt02t1Ezm81kcMcqeHd -BzbxNeiN2NmBozLQ0SERMDkNJUUFlK3ALdx9USdwTTMywRMnkgLDuRaA6m1QDi24 -RoFDjhEQREbjRD4WxJuzgvLKhF60bQnsAf5R7DkCgYBDpWBii/FkNepX9xVb5wsX -P7N3blxph132P/n13AUgCkXuMehR6zs7HMUggRpQKse2Qu9qEOVjL3jFN5ZwOKLZ -QQV2dKG6Omd6SBPGN9A2r71nWDyL7QlTK4gb6iktcQsi9YsC1S4isPRQVVAEgZC+ -k5noNMv7JLJYsIMhj31i2QKBgQDbg9HVgujz9KOiH+Zuv4PQrQ4GrovEmct3K/q1 -LlAK33iOLnYHoo+ZYpehKojbwLOl0m86QpHtCMVH8mwlbW8F9fTl3LbgtxHyTvW4 -8v50sF4XDfTm0kogDM6NVAEu43vDUfNXhlQaeZSHVUfoZiRGw3j50vyawqrAsBMe -fPNUyQKBgQCMLr1WLgnDiMx7CLXlmKdw45z0UeP+ngZOuPICX9d5DOfznuP8VgS9 -ZiwXHF8PbSdlMFPq9LkPbQTjfTLHXZx0mKl78PcFqwtryXTpUlP1qcfjE6Hl+POD -2OkWyGz7vA80+7ilQscm0L/gLIgwiGQOdBv6akLF8qDwncOX4yWOVQ== ------END RSA PRIVATE KEY----- diff --git a/FastGithub/Program.cs b/FastGithub/Program.cs index d3208c0..524414c 100644 --- a/FastGithub/Program.cs +++ b/FastGithub/Program.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using System; using System.IO; namespace FastGithub @@ -51,7 +52,7 @@ namespace FastGithub .ConfigureWebHostDefaults(web => { web.Configure(app => app.UseHttpsReverseProxy("README.html")); - web.UseKestrel(kestrel => kestrel.ListenHttpsReverseProxy("FastGithub.cer", "FastGithub.key")); + web.UseKestrel(kestrel => kestrel.ListenHttpsReverseProxy($"FastGithub_{Environment.MachineName}.cer", $"FastGithub_{Environment.MachineName}.key")); }); } }