【问题标题】:Npgsql connection with ssl certificates in .net core web api.net core web api中与ssl证书的Npgsql连接
【发布时间】:2020-10-08 11:14:05
【问题描述】:

我正在使用 NpgSqlConnection for .net core web api 项目。当前 PostgreSQL 服务器已移至另一台服务器,需要使用客户端证书进行连接。我们提供了 3 个证书文件,分别名为 client-cert.pem、client-key.pem 和 server-ca.pem。我能够通过浏览器中的 pgAdmin 使用客户端证书和密钥文件连接到服务器。但是,我无法从我的代码连接。从互联网上尝试了几种方法,但我仍然收到以下错误。

{"28000: 连接需要有效的客户端证书"}

我正在尝试的代码 sn-p 如下所示。

var connectionString = "User ID=" + _dOptions.Value.AuthenticationCredentials.UserName
               + ";Password=" + _dOptions.Value.AuthenticationCredentials.PassWord
               + ";Server=" + _dOptions.Value.Server
               + ";Port=" + _dOptions.Value.Port.ToString()
               + ";Database=" + _dOptions.Value.Database
               + ";Integrated Security=true;Pooling=true;SSL Mode=Require;Trust Server Certificate=true";

_con = new NpgsqlConnection(connectionString);
_con.ProvideClientCertificatesCallback += new ProvideClientCertificatesCallback(MyClientCertificates);
private void MyClientCertificates(X509CertificateCollection certificates)
{
      var cert = new X509Certificate("C:\\Users\\c-Anish\\Documents\\cloud_sql_replica_certs\\DEV\\client-cert.pem");
      certificates.Add(cert);
}

另外,这里我们只使用名为 client-cert.pem 的客户端证书,但是,我认为我们可能需要使用 client-key.pem ?如果是这样,我该如何添加?我在这里错过了什么?

任何帮助都将受到高度赞赏,因为我遇到了这个问题。

【问题讨论】:

  • 应该可以提供指向文件的环境变量PGSSLCERTPGSSLKEYPGSSLROOTCERT
  • 我试过了,但得到了同样的错误信息。
  • 还没有找到解决办法。谁能帮忙?

标签: c# postgresql .net-core ssl-certificate npgsql


【解决方案1】:

我有一个解决方案,并想在这里发布它,这可能会帮助面临类似问题的其他人。

它不适用于 .pem 文件。我已使用以下命令将其转换为 .pfx 文件,并且它开始正常工作。

openssl pkcs12 -inkey C:\Certs\client-key.pem -in C:\Certs\client-cert.pem -export -out C:\Certs\client-cert.pfx

参考:Certificate Authentication Support

编辑

我没有创建物理 pfx 文件,而是将这两个 pem 文件组合起来并让它工作。下面给出代码sn-p,以供日后参考。

public X509Certificate2 GetCombinedCertificateAndKey(string certificatePath, string privateKeyPath)
    {
        using var publicKey = new X509Certificate2(certificatePath);

        var privateKeyText = System.IO.File.ReadAllText(privateKeyPath);
        var privateKeyBlocks = privateKeyText.Split("-", StringSplitOptions.RemoveEmptyEntries);
        var privateKeyBytes = Convert.FromBase64String(privateKeyBlocks[1]);
        using var rsa = RSA.Create();

        if (privateKeyBlocks[0] == "BEGIN PRIVATE KEY")
        {
            rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _);
        }
        else if (privateKeyBlocks[0] == "BEGIN RSA PRIVATE KEY")
        {
            rsa.ImportRSAPrivateKey(privateKeyBytes, out _);
        }

        var keyPair = publicKey.CopyWithPrivateKey(rsa);
        var Certificate = new X509Certificate2(keyPair.Export(X509ContentType.Pfx));
        return Certificate;
    }

【讨论】:

    猜你喜欢
    • 2019-12-11
    • 1970-01-01
    • 2020-11-09
    • 2012-08-25
    • 2017-04-28
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    相关资源
    最近更新 更多