Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.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# SSL/TLS中的相互认证_C#_Wcf_Authentication_Iis_Ssl - Fatal编程技术网

C# SSL/TLS中的相互认证

C# SSL/TLS中的相互认证,c#,wcf,authentication,iis,ssl,C#,Wcf,Authentication,Iis,Ssl,我是SSL身份验证新手,我需要使用SSL在信任边界上对两个体系结构组件进行身份验证(我可以控制这两个组件)。我想我需要双向SSL身份验证,服务器和客户端都有证书 证书可以自签名吗?(即,由供应商签署,这不会使使用SSL一开始就无效?或者我是否需要第三方验证服务来确保证书的身份?) 在服务器和客户端的公钥和私钥方面,握手是如何工作的 我必须在IIS中配置服务器以使用cetificate,并随请求一起发送客户端证书(很可能是通过使用WCF进行配置),但我是否还需要执行其他任务才能完成此任务?最终,自

我是SSL身份验证新手,我需要使用SSL在信任边界上对两个体系结构组件进行身份验证(我可以控制这两个组件)。我想我需要双向SSL身份验证,服务器和客户端都有证书

证书可以自签名吗?(即,由供应商签署,这不会使使用SSL一开始就无效?或者我是否需要第三方验证服务来确保证书的身份?)

在服务器和客户端的公钥和私钥方面,握手是如何工作的


我必须在IIS中配置服务器以使用cetificate,并随请求一起发送客户端证书(很可能是通过使用WCF进行配置),但我是否还需要执行其他任务才能完成此任务?

最终,自签名实际上更复杂。除非你能完全控制两端,否则不要这样做


私钥用于对握手中发送的证书进行签名,以便对等方可以检查您是否真正拥有所发送的证书。在某些密码中,服务器私钥在生成碎片机密时也起着作用。

使用客户端和服务器证书的双向身份验证将起作用。您也可以使用自签名证书。但是,如果两个证书都是自签名的,因为它们不是由受信任的机构签名的,则需要绕过客户端和服务器上的证书验证

就证书的安装而言,应按照以下步骤进行:

服务器端

  • ServerCert.pfx已安装到LocalMachine-->个人存储

  • ClientCert.cer已安装到本地计算机-->受信任的人员存储

  • 客户端

  • ClientCert.pfx已安装到当前用户-->个人存储

  • ServerCert.cer已安装到本地计算机-->受信任存储

  • 您需要将ServerCert.cer文件发送给客户端,客户端需要将ClientCert.cer发送给您

    现在,如果您使用的是自签名证书,并且您的客户机正在访问您的服务,那么他需要绕过证书验证。下面C#中的示例代码:

    希望有帮助


    注意:从安全角度来看,不建议在生产环境中使用自签名证书或绕过证书验证。

    我同意EJP的答案,但由于您接受了另一个答案,下面是有关自签名证书问题的进一步详细信息

    可以在服务器上使用自签名证书。您只需配置所有潜在客户机以使用信任此证书。这可以通过将证书(不带私钥)导入到每台机器的可信存储中,或者在浏览器的可信证书存储库中(例如,Firefox使用自己的证书,与运行它的操作系统无关)。这里的自签名服务器证书主要是定制CA证书的特例,其中每个客户端都需要了解它可能使用的每台服务器(缺点是自签名证书不能被撤销)。这是可以的,但实际上,如果你有超过几台机器,这很快就会成为一个问题

    您的主要问题是将自签名证书作为客户端证书

    客户端证书身份验证由服务器启动,服务器向客户端发送TLS证书请求消息。此消息包含它愿意接受的证书颁发机构的名称列表。然后,客户端使用此列表选择要发送的证书:它们查找具有与此CA列表中的一个名称匹配的颁发者DN的证书(它们具有私钥)(如果需要中间CA证书来链接到此CA列表中的颁发者DN,则它们还可以使用证书链)

    如果找不到符合这些条件的证书,大多数客户端根本不会发送任何客户端证书。这将是您在尝试使用自签名客户端证书时遇到的最大问题

    解决此问题的一种方法是让服务器发送一个空列表。这为客户端提供了选择哪个证书的更多自由(然后由服务器选择是否接受证书,但无论如何都是这样)。这是TLS 1.1明确允许的,以前的版本(SSLv3/TLS 1.0)对此主题没有提及,尽管在实践中,据我所知,它也适用于大多数SSLv3/TLS 1.0堆栈。(例如,当浏览器进行自动证书选择时,这仍然会导致笨拙的交互,因为这样很难正确进行自动选择。)

    Java的
    X509TrustManager
    可以使用
    getAcceptedAssuers()
    自定义,以在TLS证书请求消息中返回空CA列表。据我所知,在C#/.Net中,
    SslStream
    RemoteCertificateValidationCallback
    没有它的等价物。据我所知,此列表是在使用IIS/
    SslStream
    时从机器的受信任证书列表构建的。(请注意,这与证书验证本身无关,只是服务器公布它可能接受哪些证书。)

    此外,如果您想对自签名证书使用客户端证书身份验证,则必须在服务器中实现自己的验证回调来执行此身份验证。一个简单的例子是从您获得的证书中提取公钥,将其与服务器的预定义列表进行比较,然后使用该预定义列表中的用户名。除非您有一种明确的方法根据您知道的内容检查自签名证书的内容,否则您就不能信任它所说的任何内容。实现一个回调函数
            System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) =>
                                                                                     {
                                                                                         return true;
                                                                                     };