|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionIn order to perform any kind of SSL encryption between a client and a server, there need to be certificates in place. Certificates can seem a bit arcane to the uninitiated, especially when mixed in with some bizarre WCF configuration settings, but never fear, it's all here. The reason I'm writing this article (my first) is that I really battled to get this working, and the information I need was scattered all over the place. I also ran into a lot of runtime errors which ended up being caused by setup issues much earlier in the process. Very very annoying. Hopefully this will save someone some trouble! I'm assuming that you are familiar with the basics of WCF and are comfortable with configuration files and the like. I'm not including any source code as the service itself is actually not particularly important, SSL is all about setup. CertificatesThis example assumes that you (like me) don't have access to a nice shiny Certificate Authority (CA) and need to make use of the makecert tool. (Sparse information can be found here.)Note: I have recently discovered this nifty Website, a free CA, who would have thought about it. You need one certificate (cert) to act as your root authority, and one to act as the actual certificate to be used for the SSL, which needs to be signed by your root authority. If you don't set up the root authority your single certificate won't be trusted, and you will start to discover this through a series of extremely annoying WCF exceptions, long after the fact. makecert -sv SignRoot.pvk -cy authority -r signroot.cer -a
sha1 -n "CN=Dev Certification Authority" -ss my -sr localmachine
Take a look at the above links to see what each of these arguments mean, it isn't terribly important, but it's nice to know. Once this command has been run and succeeded, you need to make this certificate a trusted authority. You do this by using the MMC snap in console. Go to the run window and type "mmc", hit enter. Then in the window that opens (called the "Microsoft Management Console, for those who care) perform the following actions. File -> Add/Remove Snap-in -> Add… -> Double click Certificates -> Select Computer Account and Click Next -> Finish -> Close -> OK Then select the Certificates (Local Computer) -> Personal -> Certificates node. You should see a certificate called "Dev Certificate Authority" (or whatever else you decided to call it). Move this certificate from the current node to Certificates (Local Computer) -> Trusted Root Certification Authorities -> Certificates node, drag and drop works happily. Now you have NOT the cert you need :) makecert -iv SignRoot.pvk -ic signroot.cer -cy end -pe -n
CN="localhost" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr
localmachine -sky exchange -sp
"Microsoft RSA SChannel Cryptographic Provider" -sy 12
Note that you are using the first certificate as the author for this latest one. This is important... where I have Get the signature of your cert by double clicking on the cert (Select the Certificates (Local Computer) ' Personal ' Certificates), opening the details tab, and scrolling down to the "Thumbprint" option. Select the thumbprint and copy it. Put it in Notepad or any other text editor and replace the spaces with nothing. Keep this. (Take a look here for more on how to do this, although this link is rather unnecesary.) Configure a Port with an SSL certificateNow you get to use another fun tool, httpcfg. (For more information, look here.) Firstly run the command below to check that you don't have anything running on a port you want. httpcfg query ssl
Note that there are two ports, one will work for requests to chrise, one will work for localhost, keep track of which is which. If this is your first time doing this, it should just return a newline. If there is already SSL set up on the exact IP you want to use (or if later on you need to delete any mistakes) you can use the following command, where the IP and the port are displayed as a result from the previous query. httpcfg delete ssl -i 0.0.0.0:8888
When you have finished messing about with the above two commands, run the following command to associate a given certificate (thus allowing asymmetric encryption happiness) with a given port. httpcfg set ssl -i 0.0.0.0:8012 -h abababababababababababababab
Where the last bit (ab^n) is the thumbprint you kept earlier (you did keep it right?). Great, you now have an SSL enabled port. The WCF ServiceFinally! The service configuration needs to look like this: <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior">
<serviceMetadata httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="Binding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="NewBehavior"
name="TestWCF.ServiceImplementation.TestWCFService">
<endpoint
address="https://chrise:10081/TestWCFService"
binding="basicHttpBinding"
bindingConfiguration="Binding"
name="TestWCFService.Http"
contract="TestWCF.ServiceContracts.ITestWCFService" />
<host>
<baseAddresses>
<add baseAddress="https://chrise:10081/TestWCFService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Note that the The client looks like this: <system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="TestWCFService.Http">
<security mode="Transport">
<transport clientCredentialType="None"
proxyCredentialType="None"
realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address=https://chrise:10081/TestWCFService
binding="basicHttpBinding"
bindingConfiguration="TestWCFService.Http"
contract="TestWCF.Client.TestWCFService.ITestWCFService"
name="TestWCFService.WSHttp" />
</client>
</system.serviceModel>
And that should work! Some Exceptions I Ran IntoFirstly, this will only work on your box. Why? Because no other computer in this world is dumb enough to trust your personal cert. In order to actually get your client working on another PC, you need to export your authority cert and your SSL cert, and then import them on the client's PC. This is why makecert is NOT FOR PRODUCTION. Get a real CA guys. Secondly, you should be able to browse to the endpoint when the service is running. If when you do so, you get a popup asking you about the trustworthiness of the cert, your cert isn't trusted and the client won't be able to talk to the server.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||