【WCF】使用数字证书加密通讯

    WCF使用证书非常简便,很多事情WCF都帮做好了,例如证书的检查,证书链的检查,加密解密消息的过程等,甚至证书交换和分发也帮搞定了。配置使用证书大致就下面这几个步骤:
    1. 分别给服务端和客户端申请数字证书,安装在各自的私人证书库(Personal)中。客户端启动后,WCF会默认到该库查找WCF客户端的数字证书。
    2. 将服务端的数字证书导出,安装到客户端系统的可信人员证书库(Trusted People)中。客户端启动后,WCF默认会到该库查找WCF服务的数字证书。
    3. 服务宿主配置文件修改如下。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.web>
    
<compilation debug="true" />
  
</system.web>
  
  
<system.serviceModel>
    
    
<services>
      
<service name="CertificateTest.Service.CalService" 
               behaviorConfiguration
="CalServiceBeConfig">
        
<host>
          
<baseAddresses>
            
<add baseAddress = "http://localhost:8888/" />
          
</baseAddresses>
        
</host>
        
        
<endpoint address ="CalService" 
                  binding
="wsHttpBinding"
                  contract
="CertificateTest.Contract.ICalService">
          
<identity>
          
</identity>
        
</endpoint>
        
      
</service>
    
</services>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="CalServiceBeConfig" >
          
<serviceMetadata httpGetEnabled="True"/>
          
<serviceDebug includeExceptionDetailInFaults="False" />
          
<serviceCredentials>
            
<serviceCertificate findValue="d7a95083f6c5d13c20e6a962d338a2ebea055c9c"
                                storeLocation
="CurrentUser"
                                storeName
="My"
                                x509FindType
="FindByThumbprint"/>
          
</serviceCredentials>
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
  
</system.serviceModel>
</configuration>


4. 客户端配置文件如下。Behavior中加了个clientVia是为了进行消息跟踪。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
    
    
<!--Behaviors Configuration-->
    
<behaviors>
      
<endpointBehaviors>
        
<behavior name="clientBeh">
          
<clientVia viaUri="http://localhost:8080/CalService"></clientVia>
          
<clientCredentials>
            
<!--以证书指纹作为条件在私人证书库中搜索证书-->
            
<clientCertificate
              findValue
="ffd01fef0293e479a3d170a141522e8ce1fdded4"
              storeLocation
="CurrentUser"
              storeName
="My"
              x509FindType
="FindByThumbprint"/>
          
</clientCredentials>
        
</behavior>
      
</endpointBehaviors>
    
</behaviors>
    
    
<!--Client Configuration-->
    
<client>
      
<endpoint address="http://192.168.1.167:8888/CalService"
                binding
="wsHttpBinding"
                contract
="CertificateTest.Contract.ICalService"
                behaviorConfiguration
="clientBeh"
                name
="defaultEP">
      
</endpoint>
    
</client>    
    
  
</system.serviceModel>
</configuration>

    关于客户端证书配置,不用显式指定证书的位置,甚至不用指定使用数字证书也是可以的,只要把客户端证书导入到私人证书库里就可以了。WCF会自动协商使用证书,并到上面提到证书库中去查找证书进行交换。配置如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
    
    
<!--Behaviors Configuration-->
    
<behaviors>
      
<endpointBehaviors>
        
<behavior name="clientBeh">
          
<clientVia viaUri="http://localhost:8080/CalService"></clientVia>
        
</behavior>
      
</endpointBehaviors>
    
</behaviors>
    
    
<!--Client Configuration-->
    
<client>
      
<endpoint address="http://192.168.1.167:8888/CalService"
                binding
="wsHttpBinding"
                contract
="CertificateTest.Contract.ICalService"
                behaviorConfiguration
="clientBeh"
                name
="defaultEP">
      
</endpoint>
    
</client>    
    
  
</system.serviceModel>
</configuration>

 

    下面是源码,很简单的加法例子。

    WCF契约部分代码:

using System;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace CertificateTest.Contract
{
    [ServiceContract]
    
public interface ICalService
    
{
        [OperationContract]
        
int Add(int a, int b);
    }

}

 

    WCF服务器部分代码:

using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using CertificateTest.Contract;

namespace CertificateTest.Service
{
    
public class CalService : ICalService
    
{
        
public int Add(int a, int b)
        
{
            
return a + b;
        }

    }

}

 

    WCF宿主部分代码:

using System;
using System.ServiceModel;
using CertificateTest.Service;
using CertificateTest.Contract;

namespace CertificateTest.Host
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            
using (ServiceHost host
                
= new ServiceHost(typeof(CertificateTest.Service.CalService)))
            
{
                host.Opened
+=delegate
                
{
                    Console.WriteLine(
"The service is openning.");
                }
;
                host.Open();

                Console.Read();
            }

        }

    }

}

 

    WCF客户端部分代码:

using System;
using System.ServiceModel;
using CertificateTest.Contract;

namespace CertificateTest.Client
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            
using (CalClient client = new CalClient())
            
{
                Console.WriteLine(
"100+200={0}", client.Add(100200));
            }

        }

    }


    
class CalClient : ClientBase<ICalService>, ICalService
    
{
        
public CalClient()
            : 
base()
        
{ }

        
public int Add(int a, int b)
        
{
            
return this.Channel.Add(a, b);
        }

    }

}

 

    下面是用星际强度密钥加密后的SOAP消息密文,用tcpTrace抓的。

HTTP/1.1 200 OK
Content
-Length: 2858
Content
-Type: application/soap+xml; charset=utf-8
Server: Microsoft
-HTTPAPI/1.0
Date: Thu, 
29 Jan 2009 15:55:03 GMT

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  
<s:Header>
    
<a:Action s:mustUnderstand="1" u:Id="_1">http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/SCT/Cancel</a:Action>
    <a:RelatesTo u:Id="_2">urn:uuid:58e87213-f5cc-4541-9d45-0a880db9ed24</a:RelatesTo>
    
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      
<u:Timestamp u:Id="uuid-3393524a-cd23-4a9b-8dde-01bf7d124715-72">
        
<u:Created>2009-01-29T15:55:03.390Z</u:Created>
        
<u:Expires>2009-01-29T16:00:03.390Z</u:Expires>
      
</u:Timestamp>
      
<c:DerivedKeyToken u:Id="uuid-3393524a-cd23-4a9b-8dde-01bf7d124715-67" xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">
        
<o:SecurityTokenReference>
          
<o:Reference URI="urn:uuid:74031c45-64e6-4dd2-afaf-d351503f8557" ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/sct"/>
        
</o:SecurityTokenReference>
        
<c:Offset>0</c:Offset>
        
<c:Length>24</c:Length>
        
<c:Nonce>RhG3GrRz7LzSyQG2J6y4QQ==</c:Nonce>
      
</c:DerivedKeyToken>
      
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        
<SignedInfo>
          
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
          
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
          
<Reference URI="#_0">
            
<Transforms>
              
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            
</Transforms>
            
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            
<DigestValue>BXF6YVgC7GaFcATWlFL6EsPDNMk=</DigestValue>
          
</Reference>
          
<Reference URI="#_1">
            
<Transforms>
              
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            
</Transforms>
            
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            
<DigestValue>Co+CdLM6yrXJYKmiLC3jm2Mbk1E=</DigestValue>
          
</Reference>
          
<Reference URI="#_2">
            
<Transforms>
              
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            
</Transforms>
            
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            
<DigestValue>lP2tDfmzac97N49n0kAJ/q55Qd0=</DigestValue>
          
</Reference>
          
<Reference URI="#uuid-3393524a-cd23-4a9b-8dde-01bf7d124715-72">
            
<Transforms>
              
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            
</Transforms>
            
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            
<DigestValue>zSNOO+zcFHJ+By95A6rYCASaODE=</DigestValue>
          
</Reference>
        
</SignedInfo>
        
<SignatureValue>p6WT2z73qpigpEoCd56LHCmC+OY=</SignatureValue>
        
<KeyInfo>
          
<o:SecurityTokenReference>
            
<o:Reference ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/dk" URI="#uuid-3393524a-cd23-4a9b-8dde-01bf7d124715-67"/>
          
</o:SecurityTokenReference>
        
</KeyInfo>
      
</Signature>
    
</o:Security>
  
</s:Header>
  
<s:Body u:Id="_0">
    
<t:RequestSecurityTokenResponse xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
      
<t:RequestedTokenCancelled></t:RequestedTokenCancelled>
    
</t:RequestSecurityTokenResponse>
  
</s:Body>
</s:Envelope>
posted on 2009-01-30 00:16  Hananbaum  阅读(2458)  评论(1编辑  收藏  举报