基于证书的WCF安全开发详解

基于证书的WCF安全开发详解

前几天成功建立起了一套基于证书的安全的WCF服务,很兴奋,现在做一下总结,希望大侠们指点,也希望能帮助到一些菜鸟,哈哈。

一、安全通信的基本过程

这里只做定性的理论上的分析,因为再详细一点的我也不懂。一个通信分为客户端A和服务端B,A发送请求,B响应请求。安全通信必须满足3个方面的要 求,1是保密性,即数据要经过加密,防止第三者偷窥到。2是防篡改(不知道用完整性来表示合适不),即保证B收到的数据与A发出的数据是一样的,3是抗否 认,即如果A向B发送了数据,要从技术上保证A没办法抵赖说A没发,或者说A发的与B收到的不一样。2和3从某种意义上是同义词,因为既然没人能冒充A发 数据,那么A就不能抵赖。

二、PKI系统

PKI系统由信息发送方,接收方,和CA(证书认证中心)3部分组成。PKI系统可以满足以上安全通信的所有要求。

发送方A和接收方B都有一对密钥,A有公钥A和私钥A,B有公钥B和私钥B,这些密码是由CA签发的,A和B都信任CA,信任的关系是建立在证书链 的基础上的,CA有自己的根证书Root(包含公钥Root和私钥Root),A和B的密钥实际上是由CA根据自己的密钥所签发的子密钥。PKI系统实现 了这样一个逻辑,就是如果一个PC信任一个Root证书,那么它也信任由Root签发的子证书。这一逻辑由系统软件(比如浏览器、WCF框架)所实现,我 们不必实现和管理此逻辑。所以,A和B机里的受信任的根证书区里都要包含Root的公钥,此外A和B都有自己的公钥和私钥,因为A和B都信任Root,所 以这样配置下来,A就会信任B,B也会信任A。

(1)发送信息I之前,A首先生成某种对称加密算法(比如DES,AES)的密钥Q,Q是用来加密信息I的,因为对称加密比非对称加密快很多,所以虽然我们可以用私钥A来对I加密,但却不这么做。

(2)A用公钥B对Q加密,生成Q’。

(3)A用Q对I加密,生成I’。

(4)A用私钥A做签名。具体过程是:先对(Q’+I’)做哈希(MD5、SHA1等)得S,再用私钥A对S做加密,得S’。

(5)A把(Q’+I’+S’)发给B。

(6)B用公钥A对签名做验证。具体过程是:先对((Q’+I’)做哈希(MD5、SHA1等)得S,再用公钥A对S’做解密得S’’,看S是否等于S’’,相等则有效,不等则验证失败。

(7)B用私钥B对Q’做解密得Q。

(8)用Q对I’做解密,得I。至此,A完成了向B发送I,B完成了接收I。

在第5步,信息流传于公网上,所以(Q’+I’+S’)可能被黑客X所截获,但我们可以证明,X不可能获得有用的信息(即保密性),X也不能篡改I并发给B(防篡改,检测篡改),A也不能抵赖(抗否认):

1. X要想知道I,则必须先知道Q,但它只知道Q’,所以它还要知道私钥B才能得到Q,但这是不可能的,因为只有B和CA才知道私钥B,而CA是绝对公正和安全的,B又不会把私钥B告诉别人。

2. 如果第(6)步验证成功,我们可以断定I没有被篡改过。因为假如I被篡改过,则签名S’经过公钥A解密后得的S’’,一定不会等于(Q’+I’)的哈希值S,而这与已知的条件不符,所以是不可能的。

3. 假如A要想否认自己发过I,则说明A可能把私钥A泄露给了别人Y,Y就是坏蛋。如果A说没有告诉别人,则A就在说谎,因为签名S’只有A才能生成。所以A不能抵赖。

三、一个Case

有3台PC(W,Y,P),W为客户端,W请求Y,Y又请求P,那么Y即是服务端又是客户端,P是服务端,Y和P上布署的有WCF。

要保证这三台PC间的安全通信还必须有个CA,我们可以自己架设,也可以买第三方的服务。在开发阶段,我们可以用makecert来模拟CA签发证书的过程。

具体过程如下:

(1)生成根证书

makecert -n "CN=TempCA" -r -sv TempCA.pvk TempCA.cer

TempCA就是模拟的Root证书

(2)生成W,Y,P子证书

makecert -n "CN=W" -iv TempCA.pvk -ic TempCA.cer -sv W.pvk W.cer -pe -sky exchange
pvk2pfx.exe -pvk W.pvk -spc W.cer -pfx W.pfx

==========================================================
makecert -n "CN=Y" -iv TempCA.pvk -ic TempCA.cer -sv Y.pvk Y.cer -pe -sky exchange
pvk2pfx.exe -pvk Y.pvk -spc Y.cer -pfx Y.pfx

==========================================================
makecert -n "CN=P" -iv TempCA.pvk -ic TempCA.cer -sv P.pvk P.cer -pe -sky exchange
pvk2pfx.exe -pvk P.pvk -spc P.cer -pfx P.pfx

(3)导入证书

把TempCA.cer导入W,Y,P的受信任的根证书区,把各自的pfx导入各自的个人证书区,这样每台机器都有2个证书,一个根证书,一个自己的证书。

(4)创建WCF

首先在P上创建WCF服务,再在Y上创建WCF服务并引入P的服务,再在W上创建客户端引入Y的服务。

(5)配置安全选项

W上的配置类似于:

 


    
<system.serviceModel>
        
<bindings>
            
<wsHttpBinding>
                
<binding name="ServerBinding">
                    
<security mode="Message">
                        
<message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true"/>
                    
</security>
                
</binding>
            
</wsHttpBinding>
        
</bindings>
        
<client>
            
<endpoint address="http://Y/Test.svc" binding="wsHttpBinding" bindingConfiguration="ServerBinding" contract="WcfClients.ITest" name="WSHttpBinding_ITest" behaviorConfiguration="TestEndpointBehavior">
                
<identity>
                    
<dns value="Y"/>
                
</identity>
            
</endpoint>
        
</client>
        
<behaviors>
            
<endpointBehaviors>
                
<behavior name="TestEndpointBehavior">
                    
<clientCredentials>
                        
<clientCertificate findValue="W" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
                        
<serviceCertificate>
                            
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck" />
                        
</serviceCertificate>
                    
</clientCredentials>
                
</behavior>
            
</endpointBehaviors>
        
</behaviors>
    
</system.serviceModel>

 

 

简单解释一下:

binding节配置了消息的传输方式和安全策略,并配置有name,在后面的endpoint里可以引用。服务端和客户端的binding要一致。

client节点代表客户端引用了哪些endpoint,每个endpoint的binding是什么。

endpointBehavior节点是一种扩展,针对本例,只需要配置客户端需要的具体身份凭据。服务端和客户端都可以定义 endpointBehavior,它是针对endpoint的。另外还有针对service的serviceBehavior,它只需配置在服务端,客 户端不需要。

==========================================================

Y的配置:

 


    
<system.serviceModel>
        
<client>
            
<endpoint address="http://P/Service1.svc" binding="wsHttpBinding" bindingConfiguration="ServerBinding" contract="IService1" name="WSHttpBinding_IService1" behaviorConfiguration="ServiceBehavior">
                
<identity>
                    
<dns value="P" />
                
</identity>
            
</endpoint>
        
</client>
        
<bindings>
            
<wsHttpBinding>
                
<binding name="ServerBinding">
                    
<security mode="Message">
                        
<message clientCredentialType="Certificate" />
                    
</security>
                
</binding>
            
</wsHttpBinding>
        
</bindings>
        
<services>
            
<service behaviorConfiguration="WcfSample.TestBehavior" name="WcfSample.Test">
                
<endpoint address="" binding="wsHttpBinding" contract="WcfSample.ITest" bindingConfiguration="ServerBinding">
                
</endpoint>
                
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            
</service>
        
</services>
        
<behaviors>
            
<serviceBehaviors>
                
<behavior name="WcfSample.TestSecureBehavior">
                    
<serviceMetadata httpGetEnabled="true"/>
                    
<serviceDebug includeExceptionDetailInFaults="false"/>
                    
<serviceCredentials>
                        
<serviceCertificate storeName="My"
                        storeLocation
="LocalMachine"
                        x509FindType
="FindBySubjectName"
                        findValue
="TomYang-PC"/>
                        
<clientCertificate>
                            
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck" />
                        
</clientCertificate>
                    
</serviceCredentials>
                
</behavior>
            
</serviceBehaviors>
            
<endpointBehaviors>
                
<behavior name="ServiceBehavior">
                    
<clientCredentials>
                        
<clientCertificate storeName="My"
                        storeLocation
="LocalMachine"
                        x509FindType
="FindBySubjectName"
                        findValue
="Y"/>
                        
<serviceCertificate>
                            
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
                        
</serviceCertificate>
                    
</clientCredentials>
                
</behavior>
            
</endpointBehaviors>
        
</behaviors>
    
</system.serviceModel>

 

 

Y的配置之所以如此之长,是因为它既要配置服务端,又要配置客户端。其中的service节和serviceBehavior节是与W的对应之处,也就是服务端需要什么样的凭据,客户端就要提供,反过来,客户端需要服务端提供什么样的凭据,服务端也要提供相应的配置。

==========================================================

P的配置:

 


    
<system.serviceModel>
        
<bindings>
            
<wsHttpBinding>
                
<binding name="ServerBinding">
                    
<security>
                        
<message clientCredentialType="Certificate" />
                    
</security>
                
</binding>
            
</wsHttpBinding>
        
</bindings>
        
<services>
            
<service name="Service1" behaviorConfiguration="Service1Behavior">
                
<endpoint address="" binding="wsHttpBinding" contract="IService1" bindingConfiguration="ServerBinding">
                
</endpoint>
                
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            
</service>
        
</services>
        
<behaviors>
            
<serviceBehaviors>
                
<behavior name="Service1Behavior">
                    
<serviceMetadata httpGetEnabled="true" />
                    
<serviceDebug includeExceptionDetailInFaults="true" />
                    
<serviceCredentials>
                        
<clientCertificate>
                            
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck" />
                        
</clientCertificate>
                        
<serviceCertificate findValue="P" storeName="My" x509FindType="FindBySubjectName" />
                    
</serviceCredentials>
                
</behavior>
            
</serviceBehaviors>
        
</behaviors>
    
</system.serviceModel>

 

OK, 所有代码与配置均写好了,还有要注意的一点是防火墙的问题,假如你所做的WCF使用了被防火墙屏蔽的端口时,你需要配置一下防火墙,方法可以是添加例外的 应用程序,或者添加端口。还有元数据的配置(即address为mex的那些东东),在正式的生产环境中是需要去掉的,它们可能会泄露系统敏感信息。

四、剩余的工作

这个Case只做到了安全通信,没有实现更详细的控制,比如身份识别(服务端收到请求后如何知道请求者是谁),权限控制(如何把一个用户映射到角 色,某个功能只对某些用户名角色开放)。身份识别可以使用证书的thumbprint,权限控制可以用代码访问安全性设置。这方面还没深入了解,有谁有这 方面的经验可以分享啊?

对于有些应用,比如不需要太详细的控制,只要求实现两点间的安全通信即可,那么这个Case已经够用了。

与老外讨论WCF

与老外讨论安全通信

posted on 2010-08-25 11:55 灰灰狼 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/bighuiwolf/archive/2010/08/25/1808020.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/380924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

h5分享到朋友圈_微信朋友圈创意招聘广告制作方法 H5模板

微信朋友圈招聘广告发布出去那么久了&#xff0c;为啥还是没有求职者前来应聘呢&#xff1f;那么一定是你的招聘广告不够创意&#xff0c;所以没能吸引求职者的目光。如何才能制作一个有创意更吸引求职者眼球的招聘广告呢&#xff1f;现在你只需通过制作平台的一个模板&#xf…

如何禁用win7的ASLR

ASLR&#xff08;Address space layout randomization&#xff09;使可执行程序的装载地址有一个随机偏移。虽然偏移值不大&#xff0c;但是会给内核级调试带来麻烦&#xff0c;尤其是离线查找符号表时。 经典的方法是用注册表项HKLM\SYSTEM\CurrentControlSet\Session Manage…

spring的Bean属性

我们在配置spring文件时&#xff0c;会遇到配置bean属性的问题&#xff0c;bean的作用很简单&#xff0c;就是使用该元素描述需要spring容器管理对象 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns:xsi"http://www.w3.org/2001/XML…

看了本书《答案在你心中》里面的很多问题都蛮有意思!!!

写完程序之余看看人生。想一想一些或许现在没有遇到&#xff0c;但将来某天会遇到的问题&#xff01;这本书总体还不错。摘几段看看&#xff01;&#xff01;每个人的答案都不一样&#xff01;&#xff01;哈哈《答案在你心中》为了心爱的人1 为了心爱的人&#xff0c; 你愿不愿…

还原特别慢_正手攻球最容易忽略的一步——还原

你距离标准的正手攻球可能只差一步。许多朋友在练习正手攻球一段时间以后&#xff0c;动作框架基本形成&#xff0c;有蹬转&#xff0c;能发力&#xff0c;肩部大臂都能放松&#xff0c;甚至能在击球的瞬间可以用上手指手腕的力量。但是录完视频一看&#xff0c;好像总是差那么…

Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)

Ubuntu使用教程&#xff1a;E: 无法获得锁 /var/lib/apt/lists/lock - open (11 资源临时不可用) 查看一下是否有使用apt-get的程序,终端输入:ps -aux,找到使用apt-get的程序(最后一列),查看其PID号,然后杀死其进程,输入sudo kill PID. 用sudo apt-get update时出现“ E: 无法…

Spring三种对象创建方式

1、创建方式1&#xff1a;无参构造 我们先创建一个User类&#xff1a; public class User {private String name;private int age;public User() {System.out.println("无参构造方法");}public String getName() {return name;}public void setName(String name) {t…

《Windows核心编程》の窗口过程的使用

1&#xff09;设计一个窗口过程&#xff1a; 下面的实例代码展现了经典的窗口过程的结构。窗口过程使用switch语句处理传入的消息参数uMsg&#xff0c; LRESULT CALLBACK MainWndProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM …

Anti-Screen Capture(Prevent Screen Captures)截屏与反截屏

1.数字图片使用类似与动画的方式显示&#xff0c;每次显示的是数字的一部分&#xff0c;当动态显示的时候人眼是可以分辨出具体数字的。但是截图的话就只能截取一部分&#xff0c;参考&#xff1a; cups.cs.cmu.edu/soups/2007/posters/p147_lim.pdf 2.屏蔽系统按键&#xff1…

unity中链接字符串和变量显示_理解Unity中的优化(六):字符串和文本

字符串和文本&#xff1a;在Unity项目中&#xff0c;处理字符串和文本经常会产生性能问题。在C#中&#xff0c;字符串是不变的。任何对字符串的操作都会重新分配新的字符串&#xff0c;这个代价是非常昂贵的。如果在多重循环中重复地执行字符串连接操作&#xff0c;就会造成性能…

Bean的scope属性

1、singleton&#xff08;默认值&#xff09;&#xff1a;单列对象&#xff0c;被标识为单例的对象在spring容器中只会存在一个实例 测试如下&#xff1a; 我们创建一个User类&#xff1a; public class User {private String name;private int age;public User() {System.out…

Oracle 索引扫描的五种类型

之前在讨论CBO和RBO的时候提到了索引扫描的几种类型。 Oracle Optimizer CBO RBO http://blog.csdn.net/tianlesoftware/archive/2010/08/19/5824886.aspx Oracle 索引 详解 http://blog.csdn.net/tianlesoftware/archive/2010/03/05/5347098.aspx Oracle Explain Plan http:/…

VS中标志寄存器表示

溢出标志OF(Over flow flag) OV(1) NV(0) 方向标志DF(Direction flag) DN(1) UP(0) 中断标志IF(Interrupt flag) EI(1) …

mysql修改表的结构_MySQL修改表结构

我们在修改表字段类型和约束条件的时候&#xff0c;如果表中的字段已经有值了&#xff0c;但是你修改的这个类型和字段里边的值不匹配是不允许修改的&#xff0c;就比如说你当初设置字段的时候&#xff0c;字段的值是允许存空值&#xff0c;并且字段里边已经存储空值了&#xf…

导入其他spring模块配置

列如下图中有两个spring的配置文件&#xff0c;我们想把上面的配置文件导入到下面的文件中去&#xff0c;该如何操作&#xff1a; 打开下面的配置文件&#xff0c;配置属性import,在import的resource配置上面配置文件的路径就可以了&#xff0c;如下&#xff1a; <import …

vs2019编写Linux c/c++项目

最近一直在阅读ovs的源码&#xff0c;看到用户态代码的时候&#xff0c;需要对用户态的代码进行调试&#xff0c;一开始想直接使用linux中的GDB进行调试&#xff0c;但是ovs的工程太过于复杂&#xff0c;从网上找了些文章&#xff0c;发现vs2017能够支持linux c程序的调试&…

mysql workbench 6.2_MySQL Workbench 6.2.4 下载 因为移动网络打不开官方也可能是国内网络问题 备用自己...

linux下好用的mysql gui 不多啊&#xff0c;除非在wine下 不太习惯phpmyadmin除了这个貌似在linux的就不多了&#xff0c;这里就用官方的管理工具吧win版本&#xff1a;http://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-workbench-community-6.2.4-win32.msihttp://dev…

spring属性注入的set方法注入

1、值注入 创建我们要使用的User类&#xff1a; package cn.it.bean;public class User {private String name;Overridepublic String toString() {return "User [name" name ", age" age "]";}private int age; // private Car car; // /…

MySQLdb安装的错误说明

1、从http://www.codegood.com/上下载到国外有人编译好的&#xff0c;自己就免去这一环节 2、import MySQLdb时出现如下错误&#xff1a; Warning (fromwarnings module): File "C:\Python26\lib\site-packages\MySQLdb\__init__.py", line 34fromsets importImmuta…

excel oledb mysql_OLEDB操作Excel

使用OLEDB操作Excel 的方法OleDbConnection conn null;try{//fileName 表示要操纵的Excel的文件路径&#xff0c;如果excel不存在&#xff0c;现创建它&#xff0c;可以通过模版文件复制创建。string strConn;strConn "ProviderMicrosoft.Jet.OLEDB.4.0;" "Da…