首页 > 技术文章 > 一步步改造wcf,数据加密传输-匿名客户端加密传输

birds-zhu 2019-03-18 16:15 原文

一步步改造wcf,数据加密传输-匿名客户端加密传输

百度搜索wcf加密传输,资料挺多,真真正正能用的确不多. 一是本来就很复杂,而是各位大神给的资料不足.本人今天来提供一个简易方法. 匿名客户端加密传输

1.契约

建立契约工程CalcContract,实现两个数的求和.

[ServiceContract]
public interface ICalculator
{
    [OperationContract]
    CalculatorResult Add(double x, double y);
}

[DataContract]
public class CalculatorResult
{
    /// <summary>
    /// 
    /// </summary>
    [DataMember]
    public double Result { get; set; }

    /// <summary>
    /// 
    /// </summary>
    [DataMember]
    public double X { get; set; }

    /// <summary>
    /// 
    /// </summary>
    [DataMember]
    public double Y { get; set; }
}

实现契约

public class Calculator:ICalculator
{
    public CalculatorResult Add(double x, double y)
    {
        Console.WriteLine(x.ToString() + "+" + y.ToString() + "=" + (x + y).ToString());
        return new CalculatorResult()
        {
            Result = x + y,
            X = x,
            Y = y
        };
    }
}

2.服务端实现

不用IIS实现,用控制台的方式实现,添加一个控制台程序Host,Main函数中:

class Program
{
    static void Main(string[] args)
    {
        using (ServiceHost host = new ServiceHost(typeof(Calculator)))
        {


            host.Opened += delegate
            {
                Console.WriteLine("Service Has Started.Press any key to quit.");
            };
            //通讯状态转换到已打开
            host.Open();
            Console.ReadLine();
        }
    }
}

App.config中关于wcf的配置

    <system.serviceModel>

    <behaviors>
      <serviceBehaviors>
        <behavior name="metadataBehavior" >
          <serviceMetadata httpGetEnabled="true"  />
        </behavior>
        <behavior name="behaviorConfig">
          <serviceMetadata httpGetEnabled="true"  httpGetUrl="http://127.0.0.1:8889/calculatorservice/data" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding >
        <binding name="basicHttpBindingConfiguration"/>
      </basicHttpBinding>
    </bindings>
    <services>
      <service   name="CalcContract.Calculator"  behaviorConfiguration="behaviorConfig">
        <endpoint address="http://127.0.0.1:8889/calculatorservice"
            binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfiguration" contract="CalcContract.ICalculator" >

        </endpoint>
      </service>
    </services>
  </system.serviceModel>

3.客户端

建立客户端控制台程序Client.先运行起服务端,在客户端添加服务引用,命名为CalcServiceReference,这个我就略过了.添加引用后.Main函数中代码为:

    static void Main(string[] args)
    {
        CalcServiceReference.CalculatorClient client = new CalcServiceReference.CalculatorClient();
        while(true)
        {
            double x = 100.0;
            double y = 200.0;
            CalculatorResult result = client.Add(x, y);
            Console.WriteLine(result.Result.ToString());
            Console.ReadLine();
        }

    }

Appconfig的配置如下:

 <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_ICalculator" />
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://127.0.0.1:8889/calculatorservice" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_ICalculator" contract="CalcServiceReference.ICalculator"
            name="BasicHttpBinding_ICalculator" />
    </client>
</system.serviceModel>

4.运行

先运行服务端,再运行客户端.在客户端控制台敲回车,传输100和200的服务端计算,然后服务端返回给客户端打印出300,得到100+200的正确结果.

5.明文传输

用HTTP Analyzer Full抓包查看,传输的数据为明文,如下2个图片

6.说明

这个例子中使用的basicHttpBinding绑定, 接下来我将一步步改造这个项目,使能最简单实现加密传输

7.修改服务端的配置

  • a.修改endpoint的binding为wsHttpBinding
  • b.在 节点中增加一个关于wsHttpBinding的配置wsHttpBindingConfiguration, 并且
  • c.修改endpoint下的bindingConfiguration的为wsHttpBindingConfiguration

8.制作一个证书

在vs的控制台输入:

makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=FirstCer -sky exchange –pe

makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=FirstCer -sky exchange –pe[这句不运行]

这样就制作了一个证书.

  • b.控制台打开MCC,
  • c.File-->Remove/Add Snap-in
  • d.选择Cerfiticates双击,在弹出框中选择Computer Account,点击next-->Finish,点击OK.
  • e.在左边树形目录中有了新节点:Certificates(Local Computer),点击Personal下的Certificates,发现FirstCer已经创建
  • f.右键点击FirstCer,选择COPY,
  • g.展开树形Trusted People-->Certificates,粘贴FirstCer到此处

在behaviors-->serviceBehaviors下增加

<behavior name="behaviorConfig">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:8889/calculatorservice/data" />
<serviceCredentials>
<!--指定一个 X.509 证书,用户对认证中的用户名密码加密解密-->
<serviceCertificate findValue="FirstCer" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
<clientCertificate>
<authentication certificateValidationMode="None"/>
</clientCertificate>

</serviceCredentials>
</behavior>

 并在services-service中增加这个behaviorConfig. 

 behaviorConfiguration="behaviorConfig"

 

9.更新客户端服务引用

  • a.启动服务端
  •  b.在VS中更新客户端的服务引用,appconfig得到更新.发现endpoint中增加一个节点

test

<identity>
    <certificate encodedValue="XXXXXXXXXX" />
</identity>
  • c.bindings中也自动更新节点wsHttpBinding

10.测试

  • 1.启动服务端,再启动客户端,成功了么???????

NO,客户端出错了.出错信息:

The X.509 certificate CN=FirstCer chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. The signature of the certificate cannot be verified.

- 2.客户端手动添加behaviors

-test

<behaviors>
  <endpointBehaviors>
    <behavior name="wsHttpBindingBehavior">
      <clientCredentials  >
        <serviceCertificate >
          <authentication  certificateValidationMode="None"  />
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

同时在endpoint中添加 behaviorConfiguration="wsHttpBindingBehavior"

记住:这一步非要重要,自动更新引用的时候, behaviorConfiguration="wsHttpBindingBehavior"容易丢掉.

在启动服务端,客户端,发现能通信了.并且抓包测试如下图

代码下载地址:https://download.csdn.net/download/hanghangz/11033385

说明:

  • makecert.exe 生成的正式可以在 LocalMachine或是在CurrentUser下
  • 手动补充wsHttpBindingBehavior这一步非常重要
  • 必须你自己创建一个证书,不能用我代码的encodedValue
  • 代码中包含改造前和改造后的代码,你可以按照文字一步一步来操作.

接下来,还需要研究怎么在生产环境来使用.

推荐阅读