为什么 SslStream 不发送我的客户端证书?

Why won't SslStream send my client certificate?

我已经尝试让它工作好几个小时了,但我找不到任何关于问题所在的信息。逐步执行我的代码,我最终达到了这样的部分:

clientCerts = new X509CertificateCollection(new[] { <mycert> as X509Certificate });
stream.AuthenticateAsClientAsync(<host>, clientCerts, SslProtocols.Tls12, false); // Continuation omitted

我的目标是向另一端的服务器提供客户端证书。但是我收到投诉说有 none 并且连接失败。我启动了 Wireshark,我看到服务器发送的最后一件事是:

Handshake Protocol: Certificate Request
    Handshake Type: Certificate Request (13)
    Length: 19
    Certificate types count: 2
    Certificate types (2 types)
        Certificate type: RSA Sign (1)
        Certificate type: ECDSA Sign (64)
    Signature Hash Algorithms Length: 12
    Signature Hash Algorithms (6 algorithms)
        Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
        Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
        Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
        Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
        Signature Algorithm: rsa_pkcs1_sha1 (0x0201)
        Signature Algorithm: ecdsa_sha1 (0x0203)
    Distinguished Names Length: 0

到目前为止一切顺利,自然而然,因为我在身份验证方法中指定了一个客户端证书,所以我希望它被发回,但是...

Handshake Protocol: Certificate
    Handshake Type: Certificate (11)
    Length: 3
    Certificates Length: 0

没有解释为什么,它只是拒绝发送。我在 运行 的实际测试中创建了证书并将其存储到当前用户 MY store:

var ecdsa = ECDsa.Create();
var req = new CertificateRequest($"cn={name}", ecdsa, HashAlgorithmName.SHA256);
var generatedCert= req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(1));
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) {
                    store.Open(OpenFlags.ReadWrite);
                    store.Add(generatedCert);
                    // Do stuff....
                    store.Remove(generatedCert);
}

我加载了一些 .NET Core 跟踪,发现了一些令人鼓舞的跟踪行,但没有错误。它显然将其识别为有效的可用证书,但它只是不发送它:

Event Name                                   Time MSec  Process Name            Rest  
Microsoft-System-Net-Security/CertIsType2   12,600.157  Process(84336) (84336)  ThreadID="38,972" ProcessorNumber="6" secureChannelHash="23,128,995" FormattedMessage="Certificate is of type X509Certificate2 and contains the private key." 
Microsoft-System-Net-Security/SelectedCert  12,631.155  Process(84336) (84336)  ThreadID="38,972" ProcessorNumber="6" clientCertificate="<long string that matches what I expect>" secureChannelHash="23,128,995" FormattedMessage="Selected certificate: <long string again>." 

我确实看到一些关于“errorCode:0x00090312,refContext:SafeDeleteContext_SECURITY:27780689(0x0)”的事情,但我只能说 0x00090312 对应于 SEC_I_INCOMPLETE_CREDENTIALS,这显然意味着

The server has requested client authentication, but either the supplied credentials do not include a certificate, or the certificate was not issued by a certification authority that the server trusts.

嗯...我怎么能知道服务器信任什么而不通过网络发送它来查看呢?另一端是我也在处理的代码,所以我知道它正在等待解析证书消息并检查证书,但它不能,因为 没有发送证书 。我不明白,我该怎么办?

好的,以真正的新手形式,事实证明我没有使用有效的签名算法。我必须预先指定用于键 ala

的曲线

ECDsa.Create() -> ECDsa.Create(ECCurve.CreateFromValue("1.2.840.10045.3.1.7")); 以匹配 ecdsa_secp256r1_sha256 的 secp256r1 部分(我从 here 获得该值)