What might cause System.Net Error:AcquireCredentialsHandle() failed with error 0X8009030D?
What might cause System.Net Error:AcquireCredentialsHandle() failed with error 0X8009030D?
我有一段简单的 https 连接代码,适用于一个 ssl 主机,即使根证书颁发机构不受信任也能连接(这是一个沙盒环境,所以我们不担心这会造成安全漏洞,现在),并使用 Nuget 包 OpenSSL.X509Certificate2Provider
:
从文本文件加载证书和密钥
public async Task<string> Register()
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using (var handler = new HttpClientHandler())
{
var rawcert = File.ReadAllText(@"C:\OpenSSL\bin\certTransport.pem");
var rawkey = File.ReadAllText(@"C:\OpenSSL\bin\privateKeyTransport.key");
var provider = new CertificateFromFileProvider(rawcert, rawkey);
var cert = provider.Certificate;
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback +=
(HttpRequestMessage req, X509Certificate2 cert2, X509Chain chain, SslPolicyErrors err) =>
{
return true;
};
handler.ClientCertificates.Add(cert);
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("https://{uri}/");
var response = await client.GetStringAsync("register");
return response;
}
}
}
当我将此代码指向另一台主机(应该以完全相同的方式对其进行保护)时,出现以下错误:
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
深入研究日志,我发现:
System.Net Information: 0 : [35036] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
System.Net Error: 0 : [35036] AcquireCredentialsHandle() failed with error 0X8009030D.
为此搜索堆栈,我发现许多与证书存储权限相关的错误,但本例中的客户端证书并未从存储中加载。
我还发现许多与 SecurityProtocolType 相关的问题。我已验证服务器正在使用 Tls1.2(仅)。
我从 VS 2017 Enterprise 中的单元测试调用代码 运行 Win10 x64 的管理权限。该代码包含在 .Net 4.7 Class 库中,未托管在 IIS 中。
可能是什么导致了这个问题?
更新
根据@Jeroen Mostert 在下方的有用评论,我尝试了使用 OpenSSL 的基本连接测试。稍微匿名的结果:
OpenSSL> s_client -connect {REMOVED}:443 -CAfile C:\OpenSSL\bin\archive-ii\transport-production-new\certTransport.pem
CONNECTED(000001F0)
depth=2 C = GB, O = OK, CN = {REMOVED} Root CA
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
0 s:/C=GB/O={REMOVED}/OU={REMOVED}/CN={REMOVED}
i:/C=GB/O={REMOVED}/CN={REMOVED} Issuing CA
1 s:/C=GB/O={REMOVED}/CN={REMOVED} Issuing CA
i:/C=GB/O={REMOVED}/CN={REMOVED} Root CA
2 s:/C=GB/O={REMOVED}/CN={REMOVED} Root CA
i:/C=GB/O={REMOVED}/CN={REMOVED} Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
{REMOVED}
-----END CERTIFICATE-----
subject=/C=GB/O={REMOVED}/OU={REMOVED}/CN={REMOVED}
issuer=/C=GB/O={REMOVED}/CN={REMOVED} Issuing CA
---
Acceptable client certificate CA names
/C=GB/O={REMOVED}/CN={REMOVED} Issuing CA
/C=GB/O={REMOVED}/CN={REMOVED} Root CA
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5155 bytes and written 446 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID:
Session-ID-ctx:
Master-Key: {REMOVED}
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1527164830
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
---
有什么不对吗?
我还查看了 CAPI2 日志(如评论中所建议)。这显示与不受信任的根证书相关的错误,如下所示:
这是否意味着我的验证回调不起作用 - 如果是这样,知道为什么会这样吗?
进一步更新:
如果我删除附加证书的代码行,那么错误就会消失 - 我通过了 MTLS 测试端点(但是,当然,在那里进行的 MTLS 测试失败了)。
这说明什么?证书本身有问题?
问题最终出在 OpenSSL.X509Certificate2Provider
NuGet 包的 CertificateFromFileProvider
方法的输出上。
无论出于何种原因,创建的证书都无法正常工作。采用相同的输入文件并生成 .pfx
和 OpenSSL 导致 X509Certificate2
工作正常。
我有一段简单的 https 连接代码,适用于一个 ssl 主机,即使根证书颁发机构不受信任也能连接(这是一个沙盒环境,所以我们不担心这会造成安全漏洞,现在),并使用 Nuget 包 OpenSSL.X509Certificate2Provider
:
public async Task<string> Register()
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using (var handler = new HttpClientHandler())
{
var rawcert = File.ReadAllText(@"C:\OpenSSL\bin\certTransport.pem");
var rawkey = File.ReadAllText(@"C:\OpenSSL\bin\privateKeyTransport.key");
var provider = new CertificateFromFileProvider(rawcert, rawkey);
var cert = provider.Certificate;
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback +=
(HttpRequestMessage req, X509Certificate2 cert2, X509Chain chain, SslPolicyErrors err) =>
{
return true;
};
handler.ClientCertificates.Add(cert);
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("https://{uri}/");
var response = await client.GetStringAsync("register");
return response;
}
}
}
当我将此代码指向另一台主机(应该以完全相同的方式对其进行保护)时,出现以下错误:
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
深入研究日志,我发现:
System.Net Information: 0 : [35036] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
System.Net Error: 0 : [35036] AcquireCredentialsHandle() failed with error 0X8009030D.
为此搜索堆栈,我发现许多与证书存储权限相关的错误,但本例中的客户端证书并未从存储中加载。
我还发现许多与 SecurityProtocolType 相关的问题。我已验证服务器正在使用 Tls1.2(仅)。
我从 VS 2017 Enterprise 中的单元测试调用代码 运行 Win10 x64 的管理权限。该代码包含在 .Net 4.7 Class 库中,未托管在 IIS 中。
可能是什么导致了这个问题?
更新 根据@Jeroen Mostert 在下方的有用评论,我尝试了使用 OpenSSL 的基本连接测试。稍微匿名的结果:
OpenSSL> s_client -connect {REMOVED}:443 -CAfile C:\OpenSSL\bin\archive-ii\transport-production-new\certTransport.pem
CONNECTED(000001F0)
depth=2 C = GB, O = OK, CN = {REMOVED} Root CA
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
0 s:/C=GB/O={REMOVED}/OU={REMOVED}/CN={REMOVED}
i:/C=GB/O={REMOVED}/CN={REMOVED} Issuing CA
1 s:/C=GB/O={REMOVED}/CN={REMOVED} Issuing CA
i:/C=GB/O={REMOVED}/CN={REMOVED} Root CA
2 s:/C=GB/O={REMOVED}/CN={REMOVED} Root CA
i:/C=GB/O={REMOVED}/CN={REMOVED} Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
{REMOVED}
-----END CERTIFICATE-----
subject=/C=GB/O={REMOVED}/OU={REMOVED}/CN={REMOVED}
issuer=/C=GB/O={REMOVED}/CN={REMOVED} Issuing CA
---
Acceptable client certificate CA names
/C=GB/O={REMOVED}/CN={REMOVED} Issuing CA
/C=GB/O={REMOVED}/CN={REMOVED} Root CA
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5155 bytes and written 446 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID:
Session-ID-ctx:
Master-Key: {REMOVED}
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1527164830
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
---
有什么不对吗?
我还查看了 CAPI2 日志(如评论中所建议)。这显示与不受信任的根证书相关的错误,如下所示:
这是否意味着我的验证回调不起作用 - 如果是这样,知道为什么会这样吗?
进一步更新:
如果我删除附加证书的代码行,那么错误就会消失 - 我通过了 MTLS 测试端点(但是,当然,在那里进行的 MTLS 测试失败了)。
这说明什么?证书本身有问题?
问题最终出在 OpenSSL.X509Certificate2Provider
NuGet 包的 CertificateFromFileProvider
方法的输出上。
无论出于何种原因,创建的证书都无法正常工作。采用相同的输入文件并生成 .pfx
和 OpenSSL 导致 X509Certificate2
工作正常。