SSL / TLS中的相互身份验证

时间:2012-08-04 23:31:22

标签: c# wcf authentication iis ssl

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

证书可以自签名吗? (即,由供应商签署,这不会首先使用SSL取消?或者我是否需要第三方验证服务以确保证书的身份?)

握手如何在服务器和客户端的公钥和私钥方面起作用?

我将不得不在IIS中配置服务器以使用cetificate,并使用请求发送客户端证书(最有可能通过使用WCF进行配置?),但是还有其他任务我需要做才能使其工作?

3 个答案:

答案 0 :(得分:3)

我同意EJP的回答,但由于您已经接受了另一个回答,以下是有关自签名证书的问题的详细信息。

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

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

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

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

解决此问题的方法是让服务器发送一个空列表。这为客户提供了更多的自由选择(然后由服务器决定是否接受它,但无论如何都会如此)。 TLS 1.1明确允许这一点,并且以前的版本(SSLv3 / TLS 1.0)对此主题保持沉默,尽管在实践中,就我所知,它对大多数SSLv3 / TLS 1.0堆栈都可以正常工作。 (例如,当浏览器完成自动证书选择时,这仍然会导致笨重的交互,因为这使得很难正确地进行自动选择。)

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

此外,如果要对自签名证书使用客户端证书身份验证,则必须在服务器中实现自己的验证回调以执行此身份验证。一个简单的示例是从您获得的证书中提取公钥,将其与服务器具有的预定义列表进行比较,然后使用您在该预定义列表中的用户名。除非您有明确的方法来检查其内容与您所知道的内容,否则您无法信任任何自签名证书。实现仅显示SslStream的回调将不会执行任何身份验证。任何人都可以构建具有相同名称或属性以及不同密钥的证书。 (在服务器可信证书存储中明确信任每个客户端证书几乎会更好,尽管这可能会导致TLS证书请求消息中的长CA列表。)

如果您不想依赖商业CA,请构建您自己的CA.它可能是一些工作(主要是行政),但至少你会有一个更清洁的结果系统。通过使用该CA证书配置客户端和服务器,您应该能够在不进行更改的情况下扩展到更多客户端和服务器,并且在请求客户端证书时,您还可以从正常的CA列表行为中受益。 / p>

答案 1 :(得分:2)

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

私钥用于签署握手中发送的证书,以便对等方可以检查您是否真正拥有要发送的证书。服务器私钥也在某些密码中生成分片秘密中起作用。

答案 2 :(得分:-3)

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

在安装证书方面,应按如下方式进行:

服务器端

  1. 安装到LocalMachine的ServerCert.pfx - >个人商店

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

  3. 客户端

    1. ClientCert.pfx安装到当前用户 - >个人商店

    2. 安装到本地计算机的ServerCert.cer - >受信任的商店

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

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

              System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) =>
                                                                                       {
                                                                                           return true;
                                                                                       };
      

      希望有所帮助。

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

相关问题