Client Certificate Authentication (Part 1)



https://blogs.msdn.microsoft.com/kaushal/2015/05/27/client-certificate-authentication-part-1/

SSL/TLS证书通常用于双方的加密和身份验证。在这篇博文中,我将简要地描述客户端证书认证。

客户端证书身份验证是一种基于相互证书的身份验证,客户端向服务器提供其客户端证书以证明其身份。这是SSL握手的一部分(它是可选的)。

在我们继续之前,我们需要了解。

什么是客户证书?
什么是身份验证&为什么我们需要它?

客户证书
客户证书是一个证明X.509系统的数字证书。客户端系统使用它来向远程服务器证明其身份。下面是一个简单的方法来确定证书是否是客户端证书的位置:

在“详细信息”选项卡中,预期用途的证书具有以下文本:
“向远程计算机证明您的身份”
验证证书的增强型密钥用法字段是否将OID设置为(1.3.6.1.5.5.7.3.2)。
以下是客户端证书示例的屏幕截图:

3173.060215_0710_ClientCerti1.png

请参阅RFC 5246

认证和授权
在计算机科学中,身份验证是一种用于证明参与通信的各方身份的机制。它被用于证明“你就是你说的你。”
不要与授权相混淆,授权是用来证明“你被允许执行正在尝试执行的操作”。

有几种类型的认证。以下是在IIS上广泛使用的身份验证列表(顺序不定):

匿名身份验证(无身份验证)
基本认证
客户端证书认证
摘要式身份验证
表单认证
NTLM
Kerberos
智能卡身份验证

注意:由于SSL握手发生在HTTP通信之前,客户端证书身份验证的优先级高于通过HTTP协议进行的任何其他类型的身份验证。
Kerberos,客户端证书认证和智能卡认证是相互认证机制的例子。 身份验证通常用于访问控制,您希望限制对已知用户的访问。 另一方面,授权用于确定授予用户的访问级别/特权。

在Windows上,线程是执行的基本单元。 由用户执行的任何任务由特定账户/身份的上下文中的线程执行。 身份验证是用于确定线程身份的方式之一,其特权将被线程用于执行。

SSL / TLS握手中的客户端证书身份验证

我已经在我的一篇博文中讨论过SSL握手。浏览:
http://blogs.msdn.com/b/kaushal/archive/2013/08/03/ssl-handshake-and-https-bindings-on-iis.aspx

以下是描述SSL / TLS握手的屏幕截图:

6574.060215_0710_ClientCerti2.png

客户端如上图所示发送CLIENT HELLO
在收到CLIENT HELLO后,如果服务器配置为客户端证书认证,则除了上述其他细节外,它还会将作为SERVER HELLO的一部分的专有CA名称和客户端证书请求发送给客户端。
在收到包含客户端证书请求和可分辨CA名称列表的服务器Hello时,客户端将执行以下步骤:
客户端使用SERVER HELLO中提供的CA列表来确定相互信任的CA证书。
该客户将确定由相互信任的证书颁发机构颁发的客户证书。
然后,客户端将向用户展示客户端证书列表,以便他们可以选择要发送给用户的证书。

注意:
在客户端上,客户端证书必须有一个私钥。如果没有的话,则认证被忽略。
如果服务器未在SERVER HELLO中提供专有CA名称列表,则客户端将向用户呈现其有权访问的所有客户端证书。

一经选择,客户回应下列内容中的一个:
1. 包含预主密钥的ClientKeyExchange消息
2. 包含客户端证书的证书消息(不包含私钥)。
3. CertificateVerify消息,该消息用于提供客户端证书的明确验证。此消息仅在发送客户端证书消息时发送。通过使用其私钥对客户端进行身份验证,以签署到目前为止所有消息的哈希。收件人使用签名者的公钥验证签名,从而确保它使用客户端的私钥签名。有关更多详细信息,请参阅RFC 5246。

发布此客户端和服务器使用随机数和预主密钥生成对称密钥(或主密钥),这些密钥将用于加密和解密消息以进一步通信。
两者都回应ChangeCipherSpec表明他们已经完成了这个过程。
SSL握手现在完成,双方拥有可用于加密和解密的主密钥副本。

设计问题
我们知道服务器将可分辨的CA名称列表作为SERVER HELLO的一部分。 RFC永远不会要求区分的CA名称列表应包含根CA或中级CA证书。以下是RFC5246中定义的本节的一部分:

certificate_authorities
可接受的专有名称[X501]列表
certificate_authorities,以DER编码格式表示。这些
专有名称可以为a指定所需的可分辨名称
根CA或下级CA;因此,这个消息可以用来
描述已知的根以及所需的授权空间。如果
certificate_authorities列表是空的,然后客户端可以
发送适当的ClientCertificateType的任何证书,
除非有相反的外部安排

请参阅以下博客文章以获取有关根证书和中级CA证书的信息:
http://blogs.msdn.com/b/kaushal/archive/2013/01/10/self-signed-root-ca-and-intermediate-ca-certificates.aspx

这可能会导致一些问题,即少数系统需要根CA,而很少需要中间CA出现在SERVER HELLO中发送的列表中。这使通信方在某些场合不兼容。

这两个实现都是有争议的。一方面,服务器发送的列表不能超过一定的限制(在窗口上的大小是12,228字节)。如果超过,认证将失败。中级CA的列表总是超过根CA的列表2-3倍甚至更高。这是某些系统在“可分辨CA名称”列表中发送根CA的原因之一。另一方面,中间CA名称可以在用户提供的客户端证书中随时获得,因此在证书链验证过程中可以更轻松地使用中间CA名称,因此有些系统比以前更喜欢这一点。两者都有其优点。

我个人遇到的一个例子是Apple的Safari浏览器与IIS 7或更高版本上托管的站点进行通信,这需要客户端证书进行身份验证。 Safari期望在SERVER HELLO中列出中级CA的列表。另一方面,IIS只在该列表中发送根CA.结果,身份验证失败,因为客户端无法向服务器提供客户端证书。

解决上述问题的方法是将IIS配置为不在SERVER HELLO中发送任何CA列表。为了实现这一点,请遵循以下支持文章中描述的方法3:
https://support.microsoft.com/en-us/kb/933430/

上面的文章要求您添加一个注册表项SendTrustedIssuerList,它被设置为0。

因此,服务器不会向客户端发送任何列表,但要求它通过客户端证书。客户将出示完整的客户证书列表以供选择,并且会按预期进行。

注意:在Windows Server 2012和Windows 8中,对底层认证过程进行了更改,以便:
不再支持基于CTL的受信任发行者列表管理。
默认情况下发送受信任的颁发者列表的行为已关闭:SendTrustedIssuerList注册表项的默认值现在为0(默认情况下已关闭)而不是1。
保留与以前版本的Windows操作系统的兼容性。
进一步阅读:https://technet.microsoft.com/en-in/library/hh831771.aspx

Monday, April 9, 2018 by blast