You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Web API自签名证书HTTPS连接异常求助

ASP.NET Core Web API 自签名证书HTTPS连接异常问题

我正在开发一个ASP.NET Core Web API,需要使用带有密码及关联私钥的自签名证书启用HTTPS。用户可通过应用设置表单上传并配置certificate.crt、certificate.key文件路径,以及证书密码,这些配置会保存至AppSettings.xml。

应用启动后无报错或异常,但访问API端点时返回如下错误:

Error: Client network socket disconnected before a secure TLS connection was established

注:使用CertificateLoader.LoadFromStoreCert()加载证书时,应用运行正常,但业务需求必须支持导入用户自行配置的.crt和.key文件。

2023/11/08 更新

已根据Wiktor Zychla的建议调整代码:

  • 配置Kestrel服务器的SslProtocols为SslProtocols.Tls12 | SslProtocols.Tls13,兼容系统支持的SSL配置
  • 新增LoadCertificate方法,从配置文件读取证书路径和私钥信息
  • 新增SaveCertificate方法,负责安装用户导入的证书、私钥及密码(若存在)

相关代码如下:

Kestrel配置代码

var httpHostBuilder = new WebHostBuilder()
    .UseKestrel(options =>
    {
      options.ListenAnyIP(appProperties.ServerPort, listenOptions =>
      {
        var certificate = HttpServerHandler.LoadCertificate(appProperties);

        listenOptions.UseHttps(httpsOptions =>
        {
          httpsOptions.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
          httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
          {
            if (certificate != null)
              return certificate;

            return null;
          };
        });
      });
    });

证书处理相关代码

public void SaveCertificate()
{
  if (AppProperties.CertFilePath != null && File.Exists(AppProperties.CertFilePath))
    certFilePath = AppProperties.CertFilePath;

  passwordCert = string.IsNullOrEmpty(AppProperties.PasswordCertificate) ? string.Empty : textBoxPasswordCertificate.Texts;

  if (AppProperties.KeyFilePath != null && File.Exists(AppProperties.KeyFilePath))
    keyFilePath = AppProperties.KeyFilePath;


  var certificate = new X509Certificate2(certFilePath, passwordCert, X509KeyStorageFlags.Exportable);

  if (!string.IsNullOrEmpty(keyFilePath))
  {
    byte[] privateKeyBytes = File.ReadAllBytes(keyFilePath);

    using (var privateKeyStream = new MemoryStream(privateKeyBytes))
    using (var reader = new StreamReader(privateKeyStream))
    {
      string privateKeyContent = reader.ReadToEnd();
      RSA privateKey = RSA.Create();
      privateKey.ImportFromPem(privateKeyContent);

      certificate = certificate.CopyWithPrivateKey(privateKey);
    }
  }

  InstallCertificate(certificate);

  ConfirmCertificate(certificate);

  TrustCertificate(certificate.Thumbprint);
}


public void InstallCertificate(X509Certificate2 certificate)
{
  using (X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
  {
    store.Open(OpenFlags.ReadWrite);
    store.Add(certificate);
    store.Close();
  }

  using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
  {
    store.Open(OpenFlags.ReadWrite);
    store.Add(certificate);
    store.Close();
  }
}

public void ConfirmCertificate(X509Certificate2 certificate)
{
  using (X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
  {
    store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);
    store.Certificates.Add(certificate);
    store.Close();
  }

  using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
  {
    store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);
    store.Certificates.Add(certificate);
    store.Close();
  }
}


public void TrustCertificate(string certificateThumbprint)
{
  using (X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
  {
    try
    {
      store.Open(OpenFlags.ReadWrite);

      X509Certificate2Collection certificates = store.Certificates.Find(
          X509FindType.FindByThumbprint,
          certificateThumbprint,
          validOnly: false);

      if (certificates.Count > 0)
      {
        X509Certificate2 certificate = certificates[0];
        
        X509Chain chain = new X509Chain();
        chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
        chain.Build(certificate);

        
        if (chain.ChainStatus.Length == 0)
        {
          Console.WriteLine("Trusted certificate.");
        }
        else
        {
          Console.WriteLine("Untrusted certificate.");
        }
      }
      else
      {
        Console.WriteLine("Certificate not found.");
      }
    }
    finally
    {
      store.Close();
    }
  }
}

万分感谢,期待进一步协助!顺颂时祺!


内容的提问来源于stack exchange,提问作者Gilberto Júnior

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:35:13