Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法在winforms上创建SSL/TLS安全通道,但无法在asp.net中创建_C#_Asp.net_Web Services_Ssl - Fatal编程技术网

C# 无法在winforms上创建SSL/TLS安全通道,但无法在asp.net中创建

C# 无法在winforms上创建SSL/TLS安全通道,但无法在asp.net中创建,c#,asp.net,web-services,ssl,C#,Asp.net,Web Services,Ssl,我有一个通过“添加服务引用”注册的web服务,它需要HTTPS和证书。下面是我用于实例化我的服务的代码: service = new MyReferencedWebService(); X509Certificate2 cert = new X509Certificate2(); var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Mycert.cer"

我有一个通过“添加服务引用”注册的web服务,它需要HTTPS和证书。下面是我用于实例化我的服务的代码:

        service = new MyReferencedWebService();

        X509Certificate2 cert = new X509Certificate2();

        var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Mycert.cer");
        var bytes = new byte[stream.Length];

        stream.Read(bytes, 0, bytes.Length);

        cert.Import(bytes, MYPASSWORD, X509KeyStorageFlags.DefaultKeySet);

        service.ClientCredentials.ClientCertificate.Certificate = cert;
我的配置如下所示:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="RecordGeneratorWebServiceSoapHttp">
                <security mode="Transport">
                    <transport clientCredentialType="Certificate" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://mywebserviceurl"
            binding="basicHttpBinding" bindingConfiguration="RecordGeneratorWebServiceSoapHttp"
            contract="MyService.RecordGeneratorWebServiceInterface"
            name="RecordGeneratorWebServicePort" />
    </client>
</system.serviceModel>

如果我创建一个简单的winforms.exe并使用上面的代码,我会从我的web服务得到一个响应。但是,如果我将相同的代码放入ASP.NET,我会得到以下结果:

请求被中止:无法创建SSL/TLS安全通道。

如何在ASP.NET中实现此功能

编辑: 我要补充一点。我正在使用的客户端证书绑定到智能卡,需要输入PIN才能使用。不确定这是否有什么不同


当客户端登录到应用程序时,它会提示他们输入证书PIN。在这种情况下,他们将CAC卡插入CAC读卡器。因此,也许我可以使用Request.ClientCertificate?

可以访问证书的根证书吗?如果您自己导入,则会将其导入到iis无法访问的用户证书存储中(改为导入到计算机存储中)

该类构造函数的文档说明该类将访问CSP以存储证书(用于pfx)的私钥。cer文件不需要这样做,但如果您作为应用程序池用户运行,可能仍然会遇到权限问题


尝试将应用程序池切换为以具有权限的用户身份运行,看看是否有帮助,或者尝试将证书导入计算机证书存储并从那里访问它。

您的计划是什么?换言之:

谁将输入PIN码?谁将插入智能卡

如果没有智能卡和pin,则无法在ASP.NET web服务器和web服务之间建立安全通道,因为客户端(即ASP.NET web服务器)必须访问智能卡上的私钥(并且需要pin才能访问)。我担心你要让它工作起来的唯一方法就是从智能卡上取下整个证书(包括私钥)(如果不是设计上不可能的话,这应该是非常困难的)

您的最佳行动方案是:

A) 请求“服务器证书”(非智能卡),该证书可用作ASP.NET web服务器和目标web服务之间通道的客户端证书


B) 重新设计您的解决方案,以便客户端(拥有智能卡和PIN的人)直接使用其智能卡和PIN访问安全web服务。

配置您的WCF客户端。

以防万一,请确保您的终点地址符合以下格式:

"https://hostname[:port]/ServiceDirectory/MyService.svc"
假设服务的配置正确,ASP.NET应用程序的绑定配置应为:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="RecordGeneratorWebServiceSoapHttp">
                <security mode="Transport">
                    <transport clientCredentialType="Certificate" proxyCredentialType="None" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://hostname[:port]/ServiceDirectory/MyService.svc"
            binding="basicHttpBinding" bindingConfiguration="RecordGeneratorWebServiceSoapHttp"
            contract="MyService.RecordGeneratorWebServiceInterface"
            name="RecordGeneratorWebServicePort" />
    </client>
</system.serviceModel>

您可能面临的一个问题是向您的服务传递/提供客户端证书

如果服务托管在或IIS 7.0中,则应将托管WCF服务的IIS配置为接受客户端证书

您的asp.net应用程序是WCF客户端。请参见关于使用智能卡证书和

您还需要在承载WCF服务的IIS中安装服务器SSL证书,以支持HTTPS


配置您的WCF服务

您的服务端点应包括安全http绑定以及启用httpsGetEnabled和禁用httpGetEnabled的服务行为:

<service name="MyService">
   <endpoint address="" contract="MyServiceInterface" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding"/>
</service>

<serviceBehaviors>
  <behavior name="">
    <serviceMetadata  httpGetEnabled="false" httpsGetEnabled="true" />
  </behavior>
</serviceBehaviors>

<basicHttpBinding>
   <binding name="secureHttpBinding">
      <security mode="Transport">
         <transport clientCredentialType="Certificate" proxyCredentialType="None"/>
      </security>
   </binding>
</basicHttpBinding>


这可能是由于以下原因造成的:windows版本、.net版本、证书访问权限、有效证书等。如果您还没有,请检查此问题的注释和答案。哦,是的,我有,似乎没有任何效果。您是否设置了IIS,以便它知道请求客户端证书?这是交易。当客户端登录到应用程序时,它会提示他们输入证书PIN。在这种情况下,他们将一张CAC卡插入CAC读卡器。问题就出在这里——您现在有两个通道:[客户端][WEB服务器]和[WEB服务器][WEB服务]。以前,您只有一个频道:[客户端(通过Windows窗体应用程序)][WEB SERVICE]对吗?对。我需要的是,客户端使用证书(工作)登录到web服务器,然后让web服务器使用相同的证书(不工作)访问web服务。不幸的是,这是不可能的。为了让它工作,web服务器需要能够访问客户端证书的私钥。私钥永远不会传输到web服务器(也不应该)。我看到的唯一选项是:A)尝试获取web服务信任的web服务器的服务器证书,您可以将其用作客户端证书。B) 设计一个客户端直接访问web服务的解决方案。感谢您提供的信息。我认为这行代码:cert.Import(bytes,MYPASSWORD,x509keystargeflags.DefaultKeySet)将我的证书私钥提供给了服务器。但我猜PIN和私钥之间有区别?在我的情况下,由于我的托管环境的限制,切换应用程序池身份是不可能的。