随机ca证书
This commit is contained in:
parent
8312886db7
commit
b8ac5864cc
@ -29,6 +29,31 @@ namespace FastGithub.ReverseProxy
|
|||||||
{
|
{
|
||||||
private static readonly SecureRandom secureRandom = new();
|
private static readonly SecureRandom secureRandom = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成自签名证书
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="domains"></param>
|
||||||
|
/// <param name="keySizeBits"></param>
|
||||||
|
/// <param name="validFrom"></param>
|
||||||
|
/// <param name="validTo"></param>
|
||||||
|
/// <param name="caPublicCerPath"></param>
|
||||||
|
/// <param name="caPrivateKeyPath"></param>
|
||||||
|
public static void GenerateBySelf(IEnumerable<string> 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();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成CA签名证书
|
/// 生成CA签名证书
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -39,7 +64,7 @@ namespace FastGithub.ReverseProxy
|
|||||||
/// <param name="caPublicCerPath"></param>
|
/// <param name="caPublicCerPath"></param>
|
||||||
/// <param name="caPrivateKeyPath"></param>
|
/// <param name="caPrivateKeyPath"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static X509Certificate2 Generate(IEnumerable<string> domains, int keySizeBits, DateTime validFrom, DateTime validTo, string caPublicCerPath, string caPrivateKeyPath, string? password = default)
|
public static X509Certificate2 GenerateByCa(IEnumerable<string> domains, int keySizeBits, DateTime validFrom, DateTime validTo, string caPublicCerPath, string caPrivateKeyPath, string? password = default)
|
||||||
{
|
{
|
||||||
if (File.Exists(caPublicCerPath) == false)
|
if (File.Exists(caPublicCerPath) == false)
|
||||||
{
|
{
|
||||||
@ -90,7 +115,7 @@ namespace FastGithub.ReverseProxy
|
|||||||
/// <param name="issuerPrivate"></param>
|
/// <param name="issuerPrivate"></param>
|
||||||
/// <param name="CA_PathLengthConstraint"></param>
|
/// <param name="CA_PathLengthConstraint"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static X509Certificate GenerateCertificate(IEnumerable<string> domains, AsymmetricKeyParameter subjectPublic, DateTime validFrom, DateTime validTo, string issuerName, AsymmetricKeyParameter issuerPublic, AsymmetricKeyParameter issuerPrivate, int? CA_PathLengthConstraint)
|
private static X509Certificate GenerateCertificate(IEnumerable<string> domains, AsymmetricKeyParameter subjectPublic, DateTime validFrom, DateTime validTo, string issuerName, AsymmetricKeyParameter? issuerPublic, AsymmetricKeyParameter issuerPrivate, int? CA_PathLengthConstraint)
|
||||||
{
|
{
|
||||||
var signatureFactory = issuerPrivate is ECPrivateKeyParameters
|
var signatureFactory = issuerPrivate is ECPrivateKeyParameters
|
||||||
? new Asn1SignatureFactory(X9ObjectIdentifiers.ECDsaWithSha256.ToString(), issuerPrivate)
|
? new Asn1SignatureFactory(X9ObjectIdentifiers.ECDsaWithSha256.ToString(), issuerPrivate)
|
||||||
|
|||||||
@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
@ -35,7 +36,9 @@ namespace FastGithub
|
|||||||
{
|
{
|
||||||
var loggerFactory = kestrel.ApplicationServices.GetRequiredService<ILoggerFactory>();
|
var loggerFactory = kestrel.ApplicationServices.GetRequiredService<ILoggerFactory>();
|
||||||
var logger = loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(ReverseProxy)}");
|
var logger = loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(ReverseProxy)}");
|
||||||
TryInstallCaCert(caPublicCerPath, logger);
|
|
||||||
|
GeneratorCaCert(caPublicCerPath, caPrivateKeyPath);
|
||||||
|
InstallCaCert(caPublicCerPath, logger);
|
||||||
|
|
||||||
kestrel.ListenAnyIP(443, listen =>
|
kestrel.ListenAnyIP(443, listen =>
|
||||||
listen.UseHttps(https =>
|
listen.UseHttps(https =>
|
||||||
@ -45,6 +48,51 @@ namespace FastGithub
|
|||||||
logger.LogInformation("https反向代理服务启动成功");
|
logger.LogInformation("https反向代理服务启动成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成根证书
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="caPublicCerPath"></param>
|
||||||
|
/// <param name="caPrivateKeyPath"></param>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 安装根证书
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="caPublicCerPath"></param>
|
||||||
|
/// <param name="logger"></param>
|
||||||
|
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}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取颁发给指定域名的证书
|
/// 获取颁发给指定域名的证书
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -63,7 +111,7 @@ namespace FastGithub
|
|||||||
var domains = GetDomains(host).Distinct();
|
var domains = GetDomains(host).Distinct();
|
||||||
var validFrom = DateTime.Today.AddYears(-1);
|
var validFrom = DateTime.Today.AddYears(-1);
|
||||||
var validTo = DateTime.Today.AddYears(10);
|
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);
|
}, LazyThreadSafetyMode.ExecutionAndPublication);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,29 +142,5 @@ namespace FastGithub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 安装根证书
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="caPublicCerPath"></param>
|
|
||||||
/// <param name="logger"></param>
|
|
||||||
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}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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-----
|
|
||||||
@ -35,9 +35,6 @@
|
|||||||
<None Update="FastGithub.cer">
|
<None Update="FastGithub.cer">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="FastGithub.key">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="README.html">
|
<None Update="README.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|||||||
@ -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-----
|
|
||||||
@ -2,6 +2,7 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FastGithub
|
namespace FastGithub
|
||||||
@ -51,7 +52,7 @@ namespace FastGithub
|
|||||||
.ConfigureWebHostDefaults(web =>
|
.ConfigureWebHostDefaults(web =>
|
||||||
{
|
{
|
||||||
web.Configure(app => app.UseHttpsReverseProxy("README.html"));
|
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"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user