我是 SSL 身份验证的新手,我需要通过 SSL 的信任边界对两个架构组件进行身份验证(我可以控制这两个组件)。我想我需要两种方式的 SSL 身份验证,服务器和客户端都有证书。
证书可以自签名吗?(即由供应商签名,这不会首先使用 SSL 无效?还是我需要第三方验证服务来确保证书的身份?)
就服务器和客户端的公钥和私钥而言,握手是如何工作的?
我将不得不在 IIS 中配置服务器以使用证书,并随请求发送客户端证书(很可能通过使用 WCF 进行配置?),但是我还需要执行其他任务来完成这项工作吗?
我是 SSL 身份验证的新手,我需要通过 SSL 的信任边界对两个架构组件进行身份验证(我可以控制这两个组件)。我想我需要两种方式的 SSL 身份验证,服务器和客户端都有证书。
证书可以自签名吗?(即由供应商签名,这不会首先使用 SSL 无效?还是我需要第三方验证服务来确保证书的身份?)
就服务器和客户端的公钥和私钥而言,握手是如何工作的?
我将不得不在 IIS 中配置服务器以使用证书,并随请求发送客户端证书(很可能通过使用 WCF 进行配置?),但是我还需要执行其他任务来完成这项工作吗?
我同意 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'sRemoteCertificateValidationCallback没有它的等价物。据我所知,此列表是在使用 IIS/ 时根据机器的受信任证书列表构建的SslStream。(请注意,这与证书验证本身无关,它只是关于服务器宣传它可能接受哪些证书。)
此外,如果您想将客户端证书身份验证与自签名证书一起使用,则必须在服务器中实现自己的验证回调来执行此身份验证。一个简单的示例是从您获得的证书中提取公钥,将其与服务器拥有的预定义列表进行比较,然后使用您在该预定义列表中拥有的用户名。你不能相信自签名证书所说的任何东西,除非你有一种明确的方式来检查它的内容与你知道的东西。实现一个刚刚说的回调return true;all 不会执行任何身份验证。任何人都可以构建具有相同名称或属性和不同密钥的证书。(在您的服务器可信证书存储中明确信任每个客户端证书几乎会更好,尽管这可能会导致 TLS 证书请求消息中的 CA 列表过长。)
如果您不想依赖商业 CA,请构建您自己的 CA。这可能需要一些工作(主要是管理),但至少您将拥有一个更清晰的结果系统。通过使用该 CA 证书配置您的客户端和服务器,您应该能够扩展到更多的客户端和服务器而无需更改,并且您还可以在请求客户端证书时从正常的 CA 列表行为中受益。
自签名实际上最终更复杂。除非您完全控制两端,否则不要这样做。
私钥用于签署握手中发送的证书,以便对等方可以检查您是否真正拥有您发送的证书。在某些密码中,服务器私钥也在生成分片秘密方面发挥作用。
使用客户端和服务器证书的 2 路身份验证将起作用。您也可以使用自签名证书。但是,如果两个证书都是自签名的,因为它们不是由受信任的机构签名的,那么您需要绕过客户端和服务器上的证书验证。
在安装证书方面,应按如下方式进行:
服务器端
ServerCert.pfx 安装到 LocalMachine --> 个人存储
ClientCert.cer 安装到本地机器 --> 受信任的人存储
客户端
ClientCert.pfx 安装到当前用户 --> 个人商店
ServerCert.cer 安装到本地机器 --> 可信存储
您需要将 ServerCert.cer 文件发送给客户端,而客户端需要将 ClientCert.cer 发送给您。
现在,如果您使用自签名证书并且您的客户正在访问您的服务,那么他将需要绕过证书验证。下面的 C# 示例代码:
System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) =>
{
return true;
};
希望有帮助。
注意:从安全角度来看,不建议在生产环境中使用自签名证书或绕过证书验证。