在前面几篇文章,均介绍了一些WCF服务的开发经验,对于数据的加密传输,重要性不言而喻。关于在WCF使用证书加密的重要性,在上篇随笔《
WCF开发框架形成之旅--您的数据是否需要加密》 有详细的介绍,特别对于重要的、敏感的数据,加密传输非常重要。
因此自从开始使用WCF以来,一直想使用合适的数据加密传输来解决问题,WCF常用的就是使用X509证书来实现加密,开始创建WCF服务,并顺利调用,以为一且均很美好,但是这个X509加密处理方式却令人头痛不已,一直没能顺利调通,并参考了很多www.codeproject.com上的相关文章,里面有很多不错的文章,不过很多不够系统,也说得不够具体化。本文的意图就是详细、系统化介绍如何处理证书加密的操作,方便自己及他人日常开发WCF借鉴。
首先先介绍一下前人对WCF开发中应用证书加密的一些思路介绍,个人觉得比较靠谱的是这两篇文章
1、 http://www.codeproject.com/KB/WCF/9StepsWCF.aspx
2、 Using Certificate-based Authentication and Protection with Windows Communication Foundation (WCF)
第一篇文章基本已经介绍了证书加密操作的相关步骤了:创建证书、配置服务及客户端节点。不过没有说明我们一般通过那样创建的证书,其实是临时用的测试证书,不在配置文件的certificateValidationMode属性中使用除了“None"属性外的值,否则就不能顺利运行调用服务。这个问题其实可以通过在Windows2003中部署证书服务来创建合格的证书,具体可以参考文章实现:http://www.codeproject.com/KB/WCF/wcf_certificates.aspx
另外作者可能也只是在一台开发机器上部署服务和调用客户端或者是XP系统,因此也没有考虑给IIS授权的问题,因为在Windows2003等服务器机器上,要给IIS授权才能访问证书,需要使用WinHttpCertCfg.exe或者CertMgr.exe来实现证书的授权等操作,在这方面,文章http://www.codeproject.com/KB/WCF/CustomUserNamePassAuth2.aspx 介绍的有一点靠谱了,不过了解整篇文章却无助完整测试WCF服务的应用。
综上所述,要成功部署基于X509证书加密的操作,需要这几方面的知识和操作步骤。
1、 创建WCF服务应用以及调用客户端。
2、 创建客户证书和服务端的X509证书
3、 配置服务端的配置文件,使之使用X509证书服务。
4、 授权IIS访问服务器证书
5、 在服务器证书管理中导入服务器端证书
6、 在客户端导入客户端证书,完成X509证书配置并调用服务。
下面就这几方面分别介绍相关的处理。
1、创建WCF服务应用以及调用客户端。
这个是基本的操作,客户创建适合自己的WCF开发框架,基于我的Winform开发框架扩展而成的WCF框架,是一种比较完善、高效、弹性化的开发框架,详细步骤及说明请参考随笔《基于我的Winform开发框架扩展而成的WCF开发框架》,使用这种方式构造的开发框架,各层职责比较分明,而且方便管理。
2、 创建客户证书和服务端的X509证书
在VS2008 的DOS命令提示中,输入下面的指令即可创建相关的服务器和客户端证书
makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=ParkingClient -sky exchange -pe
下面是各种参数的介绍
属性 |
解析 |
-sr |
指定的证书存储区中的注册表位置。 |
-ss |
指定证书存储的位置。 |
-a |
指定相关的算法,可以选择 MD5 算法或者 SHA1算法 |
-n |
指定证书的名称。该名称遵循X.500命名标准。简单例子如 "CN=MyName" 格式,如果没有指定/n开关,证书默认的名称是"Joe's Software Emporium"。 |
-sky |
证书键类型。可以设置为 exchange 或者 signature。 |
-pe |
证书可导出 |
创建证书成功后,我们在开发的机器上就可以看到两个不同的证书了。
要看这两个证书,需要执行下面操作, 开始-》运行-》mmc.exe=》在控制台中选择文件=》添加/删除管理单元=》添加=》选择证书=》弹出证书管理单元选择计算机账户,默认下一步确定回来,就看到下面的界面。
在上面我们可以看到创建在LocalMachine账户下的证书,我们双击查看证书可以看到这个证书是一个不受信任的证书,但是我们还是可以使用的,只是需要在Web.Config配置信息中,certificateValidationMode 属性指定为None,而不能指定其他信任值。
3、 配置服务端的配置文件,使之使用X509证书服务。
根据创建的证书信息,我们修改Web.Config文件,使之应用X509证书加密,如下所示。关键的地方是设置验证方式使用证书。
<message clientCredentialType="Certificate"/>
</security>
而证书的相关信息指定如下。
x509FindType="FindBySubjectName"
storeLocation="LocalMachine"
storeName="My"/>
上面标示证书名称是ParkingServer ,通过查找名字方式对应,并且存储在本地计算机账户、个人证书目录下的位置。
Web.Config 部分内容:
4、 授权IIS访问服务器证书
完成以上操作后,如果你的开发机器是XP,那么应该服务端是可以运行正常了,如果你的开发机器是Window2003,那么,恭喜你中奖了,运行服务后会出现下面的错误信息的:[ArgumentException: 证书“CN=ParkingServer”必须具有能够进行密钥交换的私钥。该进程必须具有访问私钥的权限。],如下图所示。
要解决上面的错误, 只需要给相应的账号分配权限即可,这里IIS访问证书密钥的权限可以通过WinHttpCertCfg.exe来处理,只需要通过命令行执行该程序即可,如下所示。
winhttpcertcfg -g -c LOCAL_MACHINE\My -s ParkingServer -a "NETWORKSERVICE"
运行命令后,在运行WCF服务,一切OK了
这里另外也介绍下WinHttpCertCfg.exe来进行处理的几个命令。
winhttpcertcfg -l -c LOCAL_MACHINE\My -s ParkingServer -a "NETWORKSERVICE"
给IIS的NETWORKSERVICE账户以基于证书名称模式授权
winhttpcertcfg -g -c LOCAL_MACHINE\My -s ParkingServer -a "NETWORKSERVICE"
给IIS的NETWORKSERVICE账户以基于证书文件模式授权
winhttpcertcfg -g -i "ParkingServer.pfx" -c LOCAL_MACHINE\My -a "NETWORKSERVICE" -p
移除账号对于证书的授权
winhttpcertcfg -r -c LOCAL_MACHINE\My -s ParkingServer -a "NETWORKSERVICE"
5、 在服务器证书管理中导入服务器端证书
完成以上步骤,如果服务配置文件正确,基本上在开发机器上不会有什么问题了,但是如果把服务部署到另外一台服务器机器上,那么就会可能出现找不到证书的错误。因为服务还没有导入创建好的证书呢。
首先我们在开发机器上,在证书的控制台中选定服务端证书并导出即可把服务端证书导出到文件中,如下图所示。
记得在导出的时候选择带私钥的选项即可,导出的文件保存为ParkingServer.pfx。然后我们在服务器中,在相同的控制台中把服务端的证书导入即可使得WCF服务在服务器中也可以正常访问了。
6、 在客户端导入客户端证书,完成X509证书配置并调用服务。
如果客户端需要部署很多个,那么每个客户端需要把第二步创建的客户端证书导入,才能正常方便服务器的WCF服务,否则会出现证书的各种提示错误。
如果这些操作完成,那么真诚恭喜你,真的可以使用WCF服务了,而且是使用了X509证书加密的WCF服务。
最后把整个测试例子放上来,供大家参考学习:https://files.cnblogs.com/wuhuacong/TestWcfService.rar