65.9K
CodeProject 正在变化。 阅读更多。
Home

互斥 SSL 身份验证简介

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (39投票s)

2012 年 2 月 8 日

CPOL

7分钟阅读

viewsIcon

747489

downloadIcon

15852

简要介绍互斥 SSL 身份验证及其握手消息。

1. 引言

相互 SSL 身份验证或基于证书的相互身份验证是指双方通过验证提供的数字证书来相互验证身份,从而确保双方都对其身份感到满意。从技术角度讲,它指的是客户端(Web 浏览器或客户端应用程序)向服务器(网站或服务器应用程序)进行身份验证,而服务器也通过验证受信任的证书颁发机构 (CA) 颁发的公钥证书/数字证书来向客户端进行身份验证。由于身份验证依赖于数字证书,因此像 Verisign 或 Microsoft Certificate Server 这样的证书颁发机构是相互身份验证过程的重要组成部分。从高层次来看,使用基于证书的相互身份验证进行身份验证并建立加密通道的过程包括以下步骤:

  1. 客户端请求访问受保护的资源。
  2. 服务器向客户端出示其证书。
  3. 客户端验证服务器的证书。
  4. 如果成功,客户端会将自己的证书发送给服务器。
  5. 服务器验证客户端的凭据。
  6. 如果成功,服务器将授予对客户端请求的受保护资源的访问权限。

Mutual SSL Authentication - Click to enlarge image

2. 背景

相互 SSL 身份验证的工作原理类似于 SSL(安全套接字层)身份验证,但增加了使用数字签名的客户端身份验证。因此,SSL 身份验证和相互 SSL 身份验证也分别非正式地称为单向 SSL 身份验证和双向 SSL 身份验证。作为开发人员,如果您有兴趣开发或能够有效地调试相互 SSL 身份验证,那么了解底层握手消息的细微之处会非常有帮助。

2.1 SSL 身份验证(服务器 -> 客户端)

在 SSL 身份验证中,客户端会收到服务器的证书,客户端计算机可能会尝试将服务器的 CA 与客户端的受信任 CA 列表进行匹配。如果颁发的 CA 受信任,客户端将验证证书是否真实且未被篡改。在这方面,客户端和服务器都使用 9 条握手消息在交换消息之前建立加密通道。

  1. 客户端发送 ClientHello 消息,提议 SSL 选项。
  2. 服务器响应 ServerHello 消息,选择 SSL 选项。
  3. 服务器发送 Certificate 消息,其中包含服务器的证书。
  4. 服务器通过 ServerHelloDone 消息结束其协商部分。
  5. 客户端在 ClientKeyExchange 消息中发送会话密钥信息(使用服务器的公钥加密)。
  6. 客户端发送 ChangeCipherSpec 消息,激活所有未来消息的已协商选项。
  7. 客户端发送 Finished 消息,让服务器检查新激活的选项。
  8. 服务器发送 ChangeCipherSpec 消息,激活所有未来消息的已协商选项。
  9. 服务器发送 Finished 消息,让客户端检查新激活的选项。

SSL authentication handshake messages

2.2 相互 SSL 身份验证(服务器 <--> 客户端)

而在相互 SSL 身份验证中,客户端和服务器通过数字证书相互验证身份,从而双方都对其身份感到满意。在这方面,客户端和服务器都使用 12 条握手消息在交换消息之前建立加密通道。

  1. 客户端发送 ClientHello 消息,提议 SSL 选项。
  2. 服务器响应 ServerHello 消息,选择 SSL 选项。
  3. 服务器发送 Certificate 消息,其中包含服务器的证书。
  4. 服务器在 CertificateRequest 消息中请求客户端证书,以便连接可以相互进行身份验证。
  5. 服务器通过 ServerHelloDone 消息结束其协商部分。
  6. 客户端响应 Certificate 消息,其中包含客户端的证书。
  7. 客户端在 ClientKeyExchange 消息中发送会话密钥信息(使用服务器的公钥加密)。
  8. 客户端发送 CertificateVerify 消息,告知服务器它拥有所发送的证书。
  9. 客户端发送 ChangeCipherSpec 消息,激活所有未来消息的已协商选项。
  10. 客户端发送 Finished 消息,让服务器检查新激活的选项。
  11. 服务器发送 ChangeCipherSpec 消息,激活所有未来消息的已协商选项。
  12. 服务器发送 Finished 消息,让客户端检查新激活的选项。

Mutual SSL authentication handshake messages

3. 捕获和分析

为了帮助读者更好地可视化底层发生了什么,我增强了微软网站上的代码示例,使其能够同时支持客户端和服务器通过相互 SSL 身份验证进行身份验证。代码示例非常简单,我不会在这里过多介绍。基本上,它的作用是客户端应用程序向服务器发送“Hello from the client.”消息,在相互 SSL 身份验证成功完成后,服务器应用程序会回复“Hello from the server.”消息。

为了捕获客户端和服务器之间传输的握手消息,我使用了一个流行的开源数据包分析工具,名为WireShark。它是一个功能强大且易于使用的数据包捕获和分析工具,可以捕获一百多种协议的消息。要了解有关如何使用此工具的更多信息,请访问其网站

但是,由于 Windows 操作系统缺乏对环回接口的支持,我不得不将客户端和服务器应用程序设置在两台不同的计算机上运行,以便使用 Wireshark 捕获它们的握手消息。运行应用程序时捕获的握手消息显示在下面的屏幕截图中,目标列中的 IP 地址“10.5.3.28”和“10.5.3.18”分别代表“客户端”和“服务器”。

Mutual SSL handshake messages - Click to enlarge image

为了进行分析和验证,我们关注的握手消息总结并列出如下:

303132 条是 TCP(传输控制协议)握手消息。

33 条 - 对应于第 2.2 节 - 项目 1。

35 条 - 包含 4 条消息,它们是:

  • Server Hello - 对应于第 2.2 节 - 项目 2。
  • Certificate - 对应于第 2.2 节 - 项目 3。
  • Certificate Request - 对应于第 2.2 节 - 项目 4。
  • Server Hello Done - 对应于第 2.2 节 - 项目 5。

38 条 - 包含 5 条消息,它们是:

  • Certificate - 对应于第 2.2 节 - 项目 6。
  • Client Key Exchange - 对应于第 2.2 节 - 项目 7。
  • Certificate Verify - 对应于第 2.2 节 - 项目 8。
  • Change Cipher Spec - 对应于第 2.2 节 - 项目 9。
  • Encrypted Handshake Message - 对应于第 2.2 节 - 项目 10 中列出的 Finish 消息。

41 条 - 包含 2 条消息,它们是:

  • Change Cipher Spec - 对应于第 2.2 节 - 项目 11。
  • Encrypted Handshake Message - 对应于第 2.2 节 - 项目 12 中列出的 Finish 消息。

第 81 条及之后的都是客户端和服务器之间交换的应用程序数据消息。

4. 使用代码

本文随附的演示项目可在本文顶部下载, intended to be run locally as opposed to the captured one shown above. This is because the certificates included in the demo project are generated for "localhost" use only. If you would like to try it out, please follow the steps outlined below to get it up and running on your workstation.

4.1 安装客户端和服务器证书

请按照以下步骤将客户端和服务器证书安装到 Windows 证书存储中。

  1. 将下载的演示项目解压缩到文件系统的任何位置。
  2. 打开管理单元窗口
    • 开始 -> 运行 -> 输入 mmc
    • 添加/删除管理单元... (Ctrl-M)
    • 为“我的用户帐户”添加证书管理单元。
  3. 展开“(受信任的根证书颁发机构)”/“证书”节点。
  4. 右键单击“证书”文件夹,然后选择“所有任务”–“导入”。
  5. 浏览到演示项目中包含的“Certificates”文件夹。
  6. 导入“MyServer.cer”并继续完成其余窗口。
  7. 重复步骤 4 和 5。
  8. 导入“MyClient.cer”证书并继续完成其余窗口。
  9. 现在,您应该会看到 2 个已导入的证书,其详细信息与下图相同(此处未显示其他无关证书)。

Certificate Store - Click to enlarge image

4.2 生成和运行解决方案

  1. 在 Visual Studio 中打开“MutualSslDemo.sln”解决方案。
  2. 按 F5 运行解决方案。
  3. 现在,您应该会看到与下图类似的结果。

SSL client and SSL server

当然,您可以通过将 SslStream.AuthenticateAsServer 函数的参数“clientCertificateRequired”设置为 true false 来在演示项目(MyServer)中切换相互 SSL 身份验证和 SSL 身份验证行为。

// Mutual SSL authentication (requires client certificate)
   sslStream.AuthenticateAsServer(certificate, true, SslProtocols.Default, true);
// SSL authentication only (do not require client certificate)
   sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Default, true);

历史

  • 2012 年 2 月 6 日:初始版本
© . All rights reserved.