为什么 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 获得该值)
我已经尝试让它工作好几个小时了,但我找不到任何关于问题所在的信息。逐步执行我的代码,我最终达到了这样的部分:
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 获得该值)