WCF X.509证书创建与IIS宿主设置

首先说明,仅仅使用证书只解决了数据明文安全问题的,但请求是否合法,还要通过其它手段,如:双向证书验证 或者 证书+用户验证的方案

VS控制台下创建证书示意:

1,默认创建证书 makecert -n "CN=www.ecepdi.com"  Wcf_EdocFileService.cer                  (-n搬发给)

2, 创建自签名搬发者证书 makecert -n "CN=www.ecepdi.com"  -r Wcf_EdocFileService.cer               (-r代表自签署)

3,创建带私钥部分.pvk的证书 makecert -n "CN=www.ecepdi.com"  -r -sv Wcf_EdocFileService.pvk Wcf_EdocFileService.cer

4,创建指定位置证书 makecert -r -pe -n "CN=www.ecepdi.com"  -sr LocalMachine -ss My -sky exchange    (-sr 位置 -n 存储位置)

参数明细参与

MSDN http://msdn.microsoft.com/zh-cn/bfsktky3(vs.80).aspx

如果是IIS做宿主的话最好采好第4种方式,将证书生成到LocalMachine 下My目录, 因为放到CurrentUser/My 下即使设置了密钥的Newwork Service/IIS_USER权限也没法正常读取密钥 ,

所以建议生成到LocalMachine/My下    makecert -r -pe -n "CN=www.ecepdi.com"  -sr LocalMachine -ss My -sky exchange

 

完成证书制作后,可以通过mmc添加单元->证书->添加本地计算机 找到个人下刚生成的证书。

你可以将证书复制到其它受信区(个人/受信人/受信任的搬发机构等),只要设置好对应的WCF节点指向这些区,当然设置None就会检索所有区域

 <authentication certificateValidationMode="None"/> 可以访问所有受信区,如果需要设置固定位置,则证书位置与WCF此节点设置要一致

 

设置IIS宿主对密钥访问权限

此时WCF IIS宿主仍无法读取到读取密钥 可以借助下面两种方式实现

1,下载FindPrivateKey.exe工具,通过命令查找指定证书

FindPrivateKey My LocalMachine -n "CN=www.ecepdi.com"    或

FindPrivateKey My LocalMachine -t "指纹密钥" 

查找到对应的密钥存放位置,然后找到此文件,在文件属性安全添加Network Service/IIS_USERS 用户的读权限

2.下载winhttpcertcfg.exe工具(还要设置IIS_USERS的权限)

WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "证书名" -a Network Service 

设置完成后,IIS宿主不是马上就可以访问密钥,所以不要急,可以iisreset命令重启IIS

 

此时在IIS宿主就可以正常访问WCF服务了 ,平时在VS调试时,大家用的都是VS的服务器,所以不会碰到此类问题,但部署到IIS就发现不能正常访问了。

建议WEB开发时,把项目属性->WEB->使用本地IIS WEB服务器,以免碰到VS里调试正常但到IIS就不正常了,就不知道怎么回事了。

 

使用证书应避免客户端与服务端时间差超过5分钟,当两端时间相差过长,则会证书安全错误.(可能原因加密过期)

 WCF IIS 站点x.509证书Web.config配置

服务端:

View Code
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="DemoService.FileService" behaviorConfiguration="DemoService.FileServiceBehavior">
<endpoint address="" binding="wsHttpBinding" contract="DemoService.IFileService" bindingConfiguration="wsHttpEndpointBinding">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DemoService.FileServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None"/>
</clientCertificate>
<serviceCertificate findValue="WcfServer"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

客户端:

View Code
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IFileService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="1073741824"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1073741824"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8066/DemoService/FileService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IFileService"
contract="Edoc.IFileService" name="WSHttpBinding_IFileService"
behaviorConfiguration="WSHttpBinding_IFileService" >
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="WSHttpBinding_IFileService">
<clientCredentials>
<clientCertificate findValue="WcfServer" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>


在测试过程中,客户端配置 <identity> <dns value="WcfServer" /></identity> 会被要求设置指向服务端的证书名,所以DNS这个位置不是IP地址而服务端的证书名。

 

WCF IIS站点 双向证书 配置

服务端:

View Code
<system.serviceModel>
<services>
<service behaviorConfiguration="DocumentFileService.FileServiceBehavior"
name="DocumentFileService.FileService">
<endpoint address="" binding="wsHttpBinding" contract="DocumentFileService.IFileService" bindingConfiguration="DocumentFileService.IFileService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DocumentFileService.FileServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" maxConcurrentInstances ="1000"/> <!-- 并发控制,最大连接数-->
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="Custom" customCertificateValidatorType="DocumentFileService.ServiceX509CertificateValidator,DocumentFileService"/>
</clientCertificate>
<serviceCertificate findValue="EdocFileServer" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="DocumentFileService.IFileService">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>

客户端:

View Code
  <system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IFileService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="1073741824" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1073741824" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://ecepdi-da2:8066/FileService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IFileService" contract="EdocFileService.IFileService" name="WSHttpBinding_IFileService" behaviorConfiguration="WSHttpBinding_IFileService">
<identity>
<dns value="EdocFileServer"/>
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="WSHttpBinding_IFileService">
<clientCredentials>
<clientCertificate findValue="EdocFileClient" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
<serviceCertificate><!--关闭客户端验证服务端证书过程-->
<authentication certificateValidationMode="Custom" customCertificateValidatorType="ECEPDI.Document.WCF_X509.ClientX509CertificateValidator,ECEPDI.Document"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>



posted on 2012-01-17 11:48  小城岁月  阅读(4334)  评论(1编辑  收藏  举报

导航

面朝大海,春暖花开!