.net - 即使有证书也无法创建 SSL/TLS 安全通道

标签 .net ssl ssl-certificate

我一直在开发一个 .Net 客户端(4.5 Framework),它需要向 Web 服务发送证书以进行身份​​验证。我已经阅读并尝试了一些建议,包括 Cannot find the certificate in either the LocalMachine store or the CurrentUser store这似乎与我的问题最相似,但仍然收到“System.Net.WebException:请求已中止:无法创建 SSL/TLS 安全通道。”。我一直在我自己的用户帐户下在我的本地计算机上运行它,以及在同一商店中安装了相同证书但具有相同效果的 Windows Server 2008 SP2。我还在某处读到该协议(protocol)可能会产生影响,因此我还允许通过命令行参数对其进行配置以在 TLS12、TLS11、TLS 和 SSL3 之间切换,所有这些都会产生相同的错误。

这是我的代码的摘录,我在其中验证我可以首先找到证书

X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
Console.WriteLine("X509 Store: Root/LocalMachine");
store.Open(OpenFlags.ReadOnly | OpenFlags.IncludeArchived);
X509Certificate2 cert = null;
foreach (var c in store.Certificates)
{
    if (!string.IsNullOrEmpty(c.Thumbprint) && 
        c.Thumbprint.ToUpper().Equals(thumbprint))
    {
        cert = c;
        Console.WriteLine("!!! Found certificate !!!, Subject [{0}]", c.Subject);
        break;
    }
}

接下来是客户端的创建和调用。

reqClient = new WebServiceClient("HTTPS_Port");
if (reqClient.ClientCredentials != null)
{
    reqClient.ClientCredentials.ClientCertificate.SetCertificate(
        StoreLocation.LocalMachine,
        StoreName.Root,
        X509FindType.FindByThumbprint,
        thumbprint);
    Console.WriteLine("Connecting with protocol [{0}] to [{1}] with certificate [{2}]",
        protocol,
        reqClient.Endpoint.Address,
        reqClient.ClientCredentials.ClientCertificate.Certificate.SubjectName.Name);
    reqClient.SubmitRequest(CreatePmResponseComplex());
    reqClient.Close();
}

还有配置...

<wsHttpBinding>
  <binding name="ServiceBinding1">
    <security mode="Transport">
      <transport clientCredentialType="Certificate"/>
    </security>
  </binding>
</wsHttpBinding>                    

<endpoint address="https://www.url.com"
        binding="wsHttpBinding"
        bindingConfiguration="ServiceBinding1"
        contract="SubmitRequest"
        name="HTTPS_Port"/> 

最后是运行的跟踪日志...

System.Net Verbose: 0 : [6620] Exiting HttpWebResponse#37251161::GetResponseStream()    -> ConnectStream#41421720
System.Net Information: 0 : [6620] TlsStream#66824994::.ctor(host=blahblah.com, #certs=1)
System.Net Information: 0 : [6620] Associating HttpWebRequest#60068066 with ConnectStream#64554036
System.Net Information: 0 : [6620] HttpWebRequest#60068066 - Request: GET /XISOAPAdapter/MessageServlet?senderParty=&amp;senderService=DWN_DEV_TAS_PIDX_RHINE_000&amp;receiverParty=&amp;receiverService=&amp;interface=PlannedMovement_PIDX_OB&amp;interfaceNamespace=urn%3Abp%3Axi%3Adwn%3Arm%3Apf%3Atasrhine%3Alogistics%3A100 HTTP/1.1

System.Net Information: 0 : [6620] ConnectStream#64554036 - Sending headers
{
Host: blahblah.com:6057
Connection: Keep-Alive
}.
System.Net Information: 0 : [6620] SecureChannel#61494432::.ctor(hostname=blahblah.com, #clientCertificates=1, encryptionPolicy=RequireEncryption)
System.Net Information: 0 : [6620] Enumerating security packages:
System.Net Information: 0 : [6620]     Negotiate
System.Net Information: 0 : [6620]     NegoExtender
System.Net Information: 0 : [6620]     Kerberos
System.Net Information: 0 : [6620]     NTLM
System.Net Information: 0 : [6620]     Schannel
System.Net Information: 0 : [6620]     Microsoft Unified Security Protocol Provider
System.Net Information: 0 : [6620]     WDigest
System.Net Information: 0 : [6620]     TSSSP
System.Net Information: 0 : [6620]     pku2u
System.Net Information: 0 : [6620]     CREDSSP
System.Net Information: 0 : [6620] SecureChannel#61494432 - Attempting to restart the session using the user-provided certificate: [Version]
  V3

[Subject]
  CN=blahblah.com, O=Acme Inc., L=Uxbridge, S=NA, C=GB
  Simple Name: blahblah.com
  DNS Name: blahblah.com

[Issuer]
  CN=Entrust Certification Authority - L1C, OU="(c) 2009 Entrust, Inc.", OU=www.entrust.net/rpa is incorporated by reference, O="Entrust, Inc.", C=US
  Simple Name: Entrust Certification Authority - L1C
  DNS Name: Entrust Certification Authority - L1C

[Serial Number]
  4C228C32

[Not Before]
  3/31/2014 10:39:58 AM

[Not After]
  4/1/2016 5:00:11 AM

[Thumbprint]
  A501A402E2DD69F2A6EE93C84859F198B7D99045

[Signature Algorithm]
  sha1RSA(1.2.840.113549.1.1.5)

[Public Key]
  Algorithm: RSA
  Length: 2048
  Key Blob: 30 82 01 0a 02 82 01 01 00 af d2 bf da 79 de 34 05 78 69 63 b3 2f f9 6f 90 ea d0 55 4d 6f 73 99 02 f9 e6 4a 53 17 81 02 dd 25 59 c8 f3 19 fa cf 6e ce a5 24 7d 5d 13 a4 22 b3 e8 91 06 2b a2 ee 2f e7 c8 51 63 10 e4 f2 3a 78 12 19 0c 60 65 c4 74 5e e7 49 1f 8e 28 cf 46 1d 4b 7a d8 95 23 96 1d 62 a0 c3 f....
System.Net Information: 0 : [6620] SecureChannel#61494432 - Left with 1 client certificates to choose from.
System.Net Information: 0 : [6620] SecureChannel#61494432 - Trying to find a matching certificate in the certificate store.
System.Net Information: 0 : [6620] SecureChannel#61494432 - Locating the private key for the certificate: [Version]
  V3

[Subject]
  CN=blahblah.com, O=Acme Inc., L=Uxbridge, S=NA, C=GB
  Simple Name: blahblah.com
  DNS Name: blahblah.com

[Issuer]
  CN=Entrust Certification Authority - L1C, OU="(c) 2009 Entrust, Inc.", OU=www.entrust.net/rpa is incorporated by reference, O="Entrust, Inc.", C=US
  Simple Name: Entrust Certification Authority - L1C
  DNS Name: Entrust Certification Authority - L1C

[Serial Number]
  4C228C32

[Not Before]
  3/31/2014 10:39:58 AM

[Not After]
  4/1/2016 5:00:11 AM

[Thumbprint]
  A501A402E2DD69F2A6EE93C84859F198B7D99045

[Signature Algorithm]
  sha1RSA(1.2.840.113549.1.1.5)

[Public Key]
  Algorithm: RSA
  Length: 2048
  Key Blob: 30 82 01 0a 02 82 01 01 00 af d2 bf da 79 de 34 05 78 69 63 b3 2f f9 6f 90 ea d0 55 4d 6f 73 99 02 f9 e6 4a 53 17 81 02 dd 25 59 c8 f3 19 fa cf 6e ce a5 24 7d 5d 13 a4 22 b3 e8 91 06 2b a2 ee 2f e7 c8 51 63 10 e4 f2 3a 78 12 19 0c 60 65 c4 74 5e e7 49 1f 8e 28 cf 46 1d 4b 7a d8 95 23 96 1d 62 a0 c3 f....
System.Net Information: 0 : [6620] SecureChannel#61494432 - Cannot find the certificate in either the LocalMachine store or the CurrentUser store.
System.Net Information: 0 : [6620] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential)
System.Net Information: 0 : [6620] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = blahblah.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [6620] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=127, returned code=ContinueNeeded).
System.Net Information: 0 : [6620] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 72a100:57ba210, targetName = blahblah.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [6620] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=AlgorithmMismatch).
System.Net Error: 0 : [6620] Exception in HttpWebRequest#60068066:: - The request was aborted: Could not create SSL/TLS secure channel..

我只是不明白程序如何找到证书,我在跟踪日志中看到了对它的引用,但它从未附加到请求中。

最佳答案

程序通过以下方式附加来自本地 Machine Store 的证书:

reqClient.ClientCredentials.ClientCertificate.SetCertificate(
    StoreLocation.LocalMachine,
    StoreName.Root,
    X509FindType.FindByThumbprint,
    thumbprint);

我正在使用 StoreName.My 正如理查德指出的那样,用户需要访问该证书中的私钥。

technet: how give user permission to a certificate in local machine store

  1. 在计算机商店注册证书
  2. 为运行您的服务的用户帐户分配私钥读取

存档2。 当您在个人容器中获得证书时,右键单击证书并选择所有任务 -> 管理私钥。您将看到私钥权限编辑器。授予用户/网络服务帐户读取权限

关于.net - 即使有证书也无法创建 SSL/TLS 安全通道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34746145/

相关文章:

c# - 创建接受参数的委托(delegate)函数

.net - 为什么 VB.NET 中的可选类属性有一个奇怪的语法?

SSL ASN1 编码例程和 x509 证书例程错误

.net - System.Uri实现ISerializable,但给出错误?

ssl - 击打 : SSL/TLS required by server but disabled in client

java - Apache Commons Http 客户端 - 注册客户端特定协议(protocol)

从 https 切换到 http 时 session 丢失 (tomcat 6.0.26)

java - 如何使用 HttpsURLConnection 连接到 https URL

ssl - 使用 tomcat 设置 SSL(自签名证书)

c# - 无法加载文件或程序集 log4net