使用证书保护 WCF 服务






4.93/5 (68投票s)
一篇描述如何使用证书颁发机构颁发的 X.509 证书来保护 WCF 服务的文章。
引言
本文提供了使用证书保护 WCF 服务的逐步指南。大多数此类文章都使用 makecert.exe 生成示例证书。这对于测试来说非常棒,但如果您想使用证书颁发机构 (CA) 颁发的证书怎么办?本文将向您展示如何使用 Microsoft 证书服务生成证书并使用它们来保护您的 WCF 服务。
必备组件
本文假设您知道如何创建和使用 WCF 服务。
您应该有两台独立的机器来执行本文中的步骤
- 客户端机器 — 这可以是您的开发系统。您应该安装 .NET Framework 3.0 或更高版本。
- 服务器机器 — 这将作为我们的 WCF 服务器以及证书颁发机构。(请注意,您可能希望有单独的服务器作为 CA。)您应该安装带有 .NET Framework 3.0 或更高版本的 Windows Server 2003。如果您没有单独的机器,建议您创建一台具有这些规范的虚拟机。这可以通过使用 Virtual PC 2007 来实现。
第 1 节:在服务器上安装 Microsoft 证书服务
您可以通过两种方式获取用于保护服务的 X.509 证书
- 从 VeriSign、Thawte、RapidSSL 等受信任的证书颁发机构购买证书。
- 创建您自己的证书颁发机构
本文重点介绍通过使用 Microsoft 证书服务创建证书的第二种方法。要安装 Microsoft 证书服务,请按照以下说明操作
- 在服务器机器上,转到“控制面板”>“添加或删除程序”
- 选择“添加/删除 Windows 组件”
- 勾选“证书服务”,然后单击“下一步”完成安装。
- 选择“独立根 CA”并单击“下一步”
- 填写 CA 标识信息
- 接受其余默认值以完成安装
第 2 节:配置客户端以信任新的证书颁发机构
Windows 预配置了一组受信任的证书颁发机构。当然,我们新的证书颁发机构不在此列表中。请按照以下步骤允许您的客户端机器信任新的证书颁发机构。
- 在客户端机器上,打开 Web 浏览器并转到 http://<服务器名称>/certsrv。这将显示一个类似于以下的页面
- 单击“下载 CA 证书、证书链或 CRL”
- 单击“下载 CA 证书链”。将 certnew.p7b 文件保存到您的文件系统。
- 加载证书 MMC 管理单元。请注意,本文中的几个步骤都需要加载此管理单元。以下说明展示了如何执行此操作,并且在后续部分中不会重复。
- 选择“开始”>“运行”并键入“mmc”以打开 Microsoft 管理控制台
- 选择“文件”>“添加/删除管理单元”
- 单击“添加”按钮
- 选择“证书”并单击“添加”按钮
- 选择“计算机帐户”并单击“下一步”按钮
- 单击“完成”按钮
- 单击“关闭”和“确定”按钮
- 展开“证书 (本地计算机)”>“受信任的根证书颁发机构”>“证书”
- 右键单击“证书”文件夹并选择“所有任务”>“导入”
- 单击“下一步”,然后单击“浏览”
- 从“文件类型”下拉列表中选择“PKCS #7 证书”
- 浏览到您在步骤 3 中保存的 certnew.p7b 文件。单击“打开”按钮
- 单击“下一步”、“下一步”和“完成”。您现在应该看到您的 CA 列为受信任的根证书颁发机构。
注意:如果您的 WCF 服务器与您的 CA 服务器不同,您需要为 WCF 服务器机器重复第 2 节。
第 3 节:创建客户端证书
本节解释如何为我们的 WCF 客户端创建证书。
- 在客户端机器上,打开 Web 浏览器并转到 http://<服务器名称>/certsrv
- 单击“请求证书”
- 单击“高级证书请求”
- 单击“向此 CA 创建并提交请求”
- 按照下图所示填写表格
- 单击“提交”并接受警告消息。您将看到一条确认消息,说明您的请求已收到并正在等待处理。
- 在服务器上,选择“开始”>“程序”>“管理工具”>“证书颁发机构”
- 展开 CA 并单击“待处理请求”。您应该在列表中看到您的客户端证书请求。
- 右键单击该请求,选择“所有任务”>“颁发”以批准证书
- 在客户端机器上,返回 http://<服务器名称>/certsrv
- 单击“查看待处理证书请求的状态”
- 单击“客户端身份验证证书”链接并接受警告消息。
- 单击“安装此证书”并接受警告消息。
至此,证书的公钥和私钥已安装在客户端机器上。下一步是在服务器上安装证书的公钥。
- 在客户端机器上加载证书 MMC 管理单元。按照这些说明加载管理单元。
- 展开“证书 (本地计算机)”>“个人”,然后单击“证书”
- 右键单击客户端证书并选择“所有任务”>“导出”
- 在证书导出向导中,单击“下一步”、“下一步”、“下一步”,选择文件名,然后单击“下一步”和“完成”
- 将导出的证书文件复制到服务器
- 在服务器机器上加载证书 MMC 管理单元。按照这些说明加载管理单元。
- 展开“证书 (本地计算机)”>“个人”。
- 右键单击“证书”,选择“所有任务”>“导入”
- 在证书导入向导中,单击“下一步”,选择您在步骤 17 中导出的文件,然后单击“下一步”、“下一步”和“完成”。客户端的公钥现在应该已安装在服务器上。
第 4 节:创建服务器证书
创建服务器证书与创建客户端证书非常相似,因此本节没有第 3 节那么多截图。
- 在服务器机器上,打开 Web 浏览器并转到 http://<服务器名称>/certsrv
- 单击“请求证书”
- 单击“高级证书请求”
- 单击“向此 CA 创建并提交请求”
- 按照下图所示填写表格
- 单击“提交”并接受警告消息。您将看到一条确认消息,说明您的请求已收到并正在等待处理。
- 在服务器上,选择“开始”>“程序”>“管理工具”>“证书颁发机构”
- 展开 CA 并单击“待处理请求”。您应该在列表中看到您的客户端证书请求。
- 右键单击该请求,选择“所有任务”>“颁发”以批准证书
- 返回 http://<服务器名称>/certsrv
- 单击“查看待处理证书请求的状态”
- 单击“服务器身份验证证书”链接并接受警告消息。
- 单击“安装此证书”并接受警告消息。
- 现在,如果您尝试在浏览器中加载您的服务,您可能会收到类似于以下的错误
System.Security.Cryptography.CryptographicException: 密钥集不存在
ArgumentException: 证书“CN=My Server Machine”必须具有能够进行密钥交换的私钥。该进程必须具有私钥的访问权限。为了解决这个问题,我们需要授予 ASPNET 或 NETWORK SERVICE 帐户读取证书的权限。这可以通过以下工具实现
下载此工具后,执行以下命令之一(取决于您的服务器配置)。C:\Program Files\Windows Resource Kits\Tools>winhttpcertcfg -g -c LOCAL_MACHINE\My -s "My Server Machine" -a ASPNET C:\Program Files\Windows Resource Kits\Tools>winhttpcertcfg -g -c LOCAL_MACHINE\My -s "My Server Machine" -a "NETWORK SERVICE"
至此,证书的公钥和私钥已安装在服务器机器上。下一步是在客户端上安装证书的公钥。
- 在服务器机器上加载证书 MMC 管理单元。按照这些说明加载管理单元。
- 展开“证书 (本地计算机)”>“个人”,然后单击“证书”
- 右键单击服务器证书并选择“所有任务”>“导出”
- 在证书导出向导中,单击“下一步”、“下一步”、“下一步”,选择文件名,然后单击“下一步”和“完成”
- 将导出的证书文件复制到客户端
- 在客户端机器上加载证书 MMC 管理单元。按照这些说明加载管理单元。
- 展开“证书 (本地计算机)”>“个人”。
- 右键单击“证书”,选择“所有任务”>“导入”
- 在证书导入向导中,单击“下一步”,选择您在步骤 17 中导出的文件,然后单击“下一步”、“下一步”和“完成”。服务器的公钥现在应该已安装在客户端上。
第 5 节:证书审查
我们现在已经完成了以下工作
- 在服务器机器上创建了证书颁发机构
- 在客户端机器上信任了证书颁发机构
- 在客户端机器上创建了客户端证书
- 在服务器机器上安装了客户端证书的公钥
- 在服务器机器上创建了服务器证书
- 在客户端机器上安装了服务器证书的公钥
第 6 节:WCF 服务配置更改
以下是 WCF 服务的 web.config 文件
- 已在自定义绑定上启用通过证书进行的消息安全。
- 客户端证书要求已在自定义行为上定义。ChainTrust 值指定必须验证证书链。
revocationMode
设置为 NoCheck。建议在生产环境中将此值设置为 Online,以防止使用已吊销的证书。这需要您拥有正确配置的吊销服务器。这超出了本文的范围,但以下页面将为您指明正确的方向 - 服务器证书的位置已在自定义行为上指定。请注意,您可能需要使用比
FindBySubjectName
更具体的搜索方法,因为您可能拥有多个主题相同的证书。FindByThumbprint
应该足以定位唯一的证书。
第 7 节:WCF 客户端配置更改
以下是 WCF 客户端的 app.config 文件
- 客户端正在与名为 myserver 的服务器通信,但服务器将自己标识为 My Server Machine(如证书中所定义)。作为一种变通方法,我们将 dns 值设置为 My Server Machine。如果证书与主机名匹配,则不需要此操作。
- 客户端证书的位置已在自定义行为上指定。
- 服务器证书身份验证选项已在自定义行为上定义。
- 已在自定义绑定上启用通过证书进行的消息安全。
您的客户端现在应该能够安全地与服务通信。
结论
正如您所看到的,将 WCF 与证书一起使用可能是一个繁琐的过程,但在某些情况下,这种安全级别是必要的。我希望本文能帮助您避免与此安全解决方案相关的一些常见陷阱。