基于证书的WCF安全开发详解
前幾天成功建立起了一套基于證書的安全的WCF服務(wù),很興奮,現(xiàn)在做一下總結(jié),希望大俠們指點(diǎn),也希望能幫助到一些菜鳥,哈哈。
一、安全通信的基本過程
這里只做定性的理論上的分析,因?yàn)樵僭敿?xì)一點(diǎn)的我也不懂。一個(gè)通信分為客戶端A和服務(wù)端B,A發(fā)送請(qǐng)求,B響應(yīng)請(qǐng)求。安全通信必須滿足3個(gè)方面的要 求,1是保密性,即數(shù)據(jù)要經(jīng)過加密,防止第三者偷窺到。2是防篡改(不知道用完整性來表示合適不),即保證B收到的數(shù)據(jù)與A發(fā)出的數(shù)據(jù)是一樣的,3是抗否 認(rèn),即如果A向B發(fā)送了數(shù)據(jù),要從技術(shù)上保證A沒辦法抵賴說A沒發(fā),或者說A發(fā)的與B收到的不一樣。2和3從某種意義上是同義詞,因?yàn)榧热粵]人能冒充A發(fā) 數(shù)據(jù),那么A就不能抵賴。
二、PKI系統(tǒng)
PKI系統(tǒng)由信息發(fā)送方,接收方,和CA(證書認(rèn)證中心)3部分組成。PKI系統(tǒng)可以滿足以上安全通信的所有要求。
發(fā)送方A和接收方B都有一對(duì)密鑰,A有公鑰A和私鑰A,B有公鑰B和私鑰B,這些密碼是由CA簽發(fā)的,A和B都信任CA,信任的關(guān)系是建立在證書鏈 的基礎(chǔ)上的,CA有自己的根證書Root(包含公鑰Root和私鑰Root),A和B的密鑰實(shí)際上是由CA根據(jù)自己的密鑰所簽發(fā)的子密鑰。PKI系統(tǒng)實(shí)現(xiàn) 了這樣一個(gè)邏輯,就是如果一個(gè)PC信任一個(gè)Root證書,那么它也信任由Root簽發(fā)的子證書。這一邏輯由系統(tǒng)軟件(比如瀏覽器、WCF框架)所實(shí)現(xiàn),我 們不必實(shí)現(xiàn)和管理此邏輯。所以,A和B機(jī)里的受信任的根證書區(qū)里都要包含Root的公鑰,此外A和B都有自己的公鑰和私鑰,因?yàn)锳和B都信任Root,所 以這樣配置下來,A就會(huì)信任B,B也會(huì)信任A。
(1)發(fā)送信息I之前,A首先生成某種對(duì)稱加密算法(比如DES,AES)的密鑰Q,Q是用來加密信息I的,因?yàn)閷?duì)稱加密比非對(duì)稱加密快很多,所以雖然我們可以用私鑰A來對(duì)I加密,但卻不這么做。
(2)A用公鑰B對(duì)Q加密,生成Q’。
(3)A用Q對(duì)I加密,生成I’。
(4)A用私鑰A做簽名。具體過程是:先對(duì)(Q’+I’)做哈希(MD5、SHA1等)得S,再用私鑰A對(duì)S做加密,得S’。
(5)A把(Q’+I’+S’)發(fā)給B。
(6)B用公鑰A對(duì)簽名做驗(yàn)證。具體過程是:先對(duì)((Q’+I’)做哈希(MD5、SHA1等)得S,再用公鑰A對(duì)S’做解密得S’’,看S是否等于S’’,相等則有效,不等則驗(yàn)證失敗。
(7)B用私鑰B對(duì)Q’做解密得Q。
(8)用Q對(duì)I’做解密,得I。至此,A完成了向B發(fā)送I,B完成了接收I。
在第5步,信息流傳于公網(wǎng)上,所以(Q’+I’+S’)可能被黑客X所截獲,但我們可以證明,X不可能獲得有用的信息(即保密性),X也不能篡改I并發(fā)給B(防篡改,檢測(cè)篡改),A也不能抵賴(抗否認(rèn)):
1. X要想知道I,則必須先知道Q,但它只知道Q’,所以它還要知道私鑰B才能得到Q,但這是不可能的,因?yàn)橹挥蠦和CA才知道私鑰B,而CA是絕對(duì)公正和安全的,B又不會(huì)把私鑰B告訴別人。
2. 如果第(6)步驗(yàn)證成功,我們可以斷定I沒有被篡改過。因?yàn)榧偃鏘被篡改過,則簽名S’經(jīng)過公鑰A解密后得的S’’,一定不會(huì)等于(Q’+I’)的哈希值S,而這與已知的條件不符,所以是不可能的。
3. 假如A要想否認(rèn)自己發(fā)過I,則說明A可能把私鑰A泄露給了別人Y,Y就是壞蛋。如果A說沒有告訴別人,則A就在說謊,因?yàn)楹灻鸖’只有A才能生成。所以A不能抵賴。
三、一個(gè)Case
有3臺(tái)PC(W,Y,P),W為客戶端,W請(qǐng)求Y,Y又請(qǐng)求P,那么Y即是服務(wù)端又是客戶端,P是服務(wù)端,Y和P上布署的有WCF。
要保證這三臺(tái)PC間的安全通信還必須有個(gè)CA,我們可以自己架設(shè),也可以買第三方的服務(wù)。在開發(fā)階段,我們可以用makecert來模擬CA簽發(fā)證書的過程。
具體過程如下:
(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)導(dǎo)入證書
把TempCA.cer導(dǎo)入W,Y,P的受信任的根證書區(qū),把各自的pfx導(dǎo)入各自的個(gè)人證書區(qū),這樣每臺(tái)機(jī)器都有2個(gè)證書,一個(gè)根證書,一個(gè)自己的證書。
(4)創(chuàng)建WCF
首先在P上創(chuàng)建WCF服務(wù),再在Y上創(chuàng)建WCF服務(wù)并引入P的服務(wù),再在W上創(chuàng)建客戶端引入Y的服務(wù)。
(5)配置安全選項(xiàng)
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>
?
?
簡(jiǎn)單解釋一下:
binding節(jié)配置了消息的傳輸方式和安全策略,并配置有name,在后面的endpoint里可以引用。服務(wù)端和客戶端的binding要一致。
client節(jié)點(diǎn)代表客戶端引用了哪些endpoint,每個(gè)endpoint的binding是什么。
endpointBehavior節(jié)點(diǎn)是一種擴(kuò)展,針對(duì)本例,只需要配置客戶端需要的具體身份憑據(jù)。服務(wù)端和客戶端都可以定義 endpointBehavior,它是針對(duì)endpoint的。另外還有針對(duì)service的serviceBehavior,它只需配置在服務(wù)端,客 戶端不需要。
==========================================================
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的配置之所以如此之長(zhǎng),是因?yàn)樗纫渲梅?wù)端,又要配置客戶端。其中的service節(jié)和serviceBehavior節(jié)是與W的對(duì)應(yīng)之處,也就是服務(wù)端需要什么樣的憑據(jù),客戶端就要提供,反過來,客戶端需要服務(wù)端提供什么樣的憑據(jù),服務(wù)端也要提供相應(yīng)的配置。
==========================================================
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, 所有代碼與配置均寫好了,還有要注意的一點(diǎn)是防火墻的問題,假如你所做的WCF使用了被防火墻屏蔽的端口時(shí),你需要配置一下防火墻,方法可以是添加例外的 應(yīng)用程序,或者添加端口。還有元數(shù)據(jù)的配置(即address為mex的那些東東),在正式的生產(chǎn)環(huán)境中是需要去掉的,它們可能會(huì)泄露系統(tǒng)敏感信息。
四、剩余的工作
這個(gè)Case只做到了安全通信,沒有實(shí)現(xiàn)更詳細(xì)的控制,比如身份識(shí)別(服務(wù)端收到請(qǐng)求后如何知道請(qǐng)求者是誰),權(quán)限控制(如何把一個(gè)用戶映射到角 色,某個(gè)功能只對(duì)某些用戶名角色開放)。身份識(shí)別可以使用證書的thumbprint,權(quán)限控制可以用代碼訪問安全性設(shè)置。這方面還沒深入了解,有誰有這 方面的經(jīng)驗(yàn)可以分享啊?
對(duì)于有些應(yīng)用,比如不需要太詳細(xì)的控制,只要求實(shí)現(xiàn)兩點(diǎn)間的安全通信即可,那么這個(gè)Case已經(jīng)夠用了。
與老外討論WCF
與老外討論安全通信
posted on 2010-08-25 11:55 灰灰狼 閱讀(...) 評(píng)論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/bighuiwolf/archive/2010/08/25/1808020.html
總結(jié)
以上是生活随笔為你收集整理的基于证书的WCF安全开发详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京环球影城快速票怎么买
- 下一篇: 看了本书《答案在你心中》里面的很多问题都