Click here to Skip to main content
Click here to Skip to main content

SSL with Self-hosted WCF Service

, 1 Mar 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
An article on the sometimes esoteric nature of certificates and WCF


In 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.


This 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.
The following command (run in a the Visual Studio command prompt) will create your root certificate, no, I didn't come up with this myself, you can find some nice examples all over the place, for example here).

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.

Personal Certificates

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.

Trusted Certificates

Now you have NOT the cert you need Smile | :)
You have made yourself able to create trusted certs though, which is nice.
Now you have to create another cert, which you are actually going to use.
Run makecert again, but run it as follows...

makecert -iv SignRoot.pvk -ic signroot.cer -cy end -pe -n
    CN="localhost" -eku -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 localhost you need to put the DNS name of your box. In other words, if you deploy your service such that its endpoint reads http://bob:10010/Service then the name needs to be bob. In addition, you are going to need to do this for each host you need to run as (yes, so one for bob and another one for localhost).

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.

Thumbprint with carefully sprayed values

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.)
You have your certs set up.

Configure a Port with an SSL certificate

Now 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
Mine looks like this

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

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.
Note that the IP is a special one indicating every IP on this PC.

httpcfg set ssl -i -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 Service

Most of the work that needs to be done in WCF service for SSL is in the configuration. I prefer configuration files myself, but this can also be done in code.

The service configuration needs to look like this:

<?xml version="1.0" encoding="utf-8" ?>
        <behavior name="NewBehavior">
          <serviceMetadata httpsGetEnabled="true"/>
        <binding name="Binding">
          <security mode="Transport">
            <transport clientCredentialType="None"/>
      <service behaviorConfiguration="NewBehavior" 
          contract="TestWCF.ServiceContracts.ITestWCFService" />
            <add baseAddress="https://chrise:10081/TestWCFService" />

Note that the httpsGetEnabled is set to true. This means that even your mex is encrypted, nifty! Also note that chrise which is the hostname in this case MUST have a corresponding certificate, or no dice.
I'm using the basic HTTP binding. You could do it with wsHTTP as well, but what's the point of getting encrypted messages if your entire transport is encrypted anyways?
Note that clientCredentialType is set to none, this is just to simplify the whole solution, otherwise we get into a whole other article.

The client looks like this:

            <binding name="TestWCFService.Http">
                <security mode="Transport">
                    <transport clientCredentialType="None" 
                        realm="" />
        <endpoint address=https://chrise:10081/TestWCFService 
            name="TestWCFService.WSHttp" />

And that should work!

Some Exceptions I Ran Into

Firstly, 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.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior)
United Kingdom United Kingdom
Chris is a full time software developer in London, UK.
He has a BSc in computer science and is busy taking courses in the MCTS stream.

Comments and Discussions

QuestionnetTcpBinding Pinmembershoar22-Jan-15 6:22 
QuestionHow to change http to https in Self-hosted (OwinSelfhost) WebApi service PinmemberMember 112017622-Nov-14 23:22 
GeneralThank you PinmemberMember 306543927-Aug-14 22:08 
QuestionWhy not use this?? PinmemberSkeletor2311-Jun-14 2:49 
QuestionWindows 7 PinmemberAlexandros Pappas6-Feb-14 5:27 
AnswerRe: Windows 7 PinmemberPalisade6-Feb-14 16:30 
GeneralRe: Windows 7 PinmemberBill Son16-Jan-15 9:50 
GeneralMy vote of 5 PinmemberJerleth.1-Feb-13 5:38 
GeneralMy vote of 5 Pinmembervlad_pol@hotmail.com17-Aug-12 6:16 
GeneralMy vote of 5 Pinmemberromull28-May-12 4:35 
QuestionThank you PinmemberCraig James16-May-12 23:13 
QuestionThank you Chris PinmemberMember 777629326-Apr-12 4:53 
GeneralMy vote of 5 PinmemberMember 777629326-Apr-12 4:48 
QuestionAccessing this services from different machine Pinmemberdheenadhayalan24-Jan-12 1:27 
QuestionNot working in Win2003 PinmemberMember 145720923-Jun-11 18:42 
QuestionStill unable to consume HTTPS hosted WCF service in OOB Silverlight 4 application Pinmembercjmakwana19-Jun-11 5:52 
GeneralMy vote of 5 Pinmember4izh25-May-11 9:43 
GeneralMy vote of 5 Pinmemberts-swann12-May-11 4:25 
QuestionTIMEOUT PROBLEM PinmemberMember 775853116-Mar-11 6:38 
General"The security certificate for host 'localhost' does not match the name of the page you are trying to view" Pinmemberrondo_schwartz29-Jan-11 21:53 
Generalthanks for this.. but one question.. PinmemberRichard P S21-May-10 2:59 
GeneralMore service detail please. PinmemberSteve Cav18-May-10 19:16 
GeneralRe: More service detail please. Pinmemberanarchistic18-May-10 23:59 
GeneralRe: More service detail please. PinmemberSteve Cav19-May-10 14:10 
GeneralRe: More service detail please. Pinmemberanarchistic19-May-10 23:31 
General.AddressAlreadyInUseException PinmemberSteve Cav17-May-10 16:04 
GeneralRe: .AddressAlreadyInUseException Pinmemberanarchistic18-May-10 13:43 
General2nd makecert fails for me Pinmemberpatc4-May-10 6:22 
GeneralRe: 2nd makecert fails for me - Figured it out Pinmemberpatc4-May-10 9:21 
Generalstill facing issue. please help .. please reply ASAP Pinmembersehariqbal1-Feb-10 6:04 
I did all you steps and got this error when try to run from IIS:

No protocol binding matches the given address 'https://simsltd-e2eee48:10081/WCFServiceCertificate3'. Protocol bindings are configured at the Site level in IIS or WAS configuration.

and when i try to run with url
the page can't be display error occur.

can you please help i am stuck in to this issue from last 3 days. plz help.
Then i actually have to more to Transport Certificate Service creation and my project is stuck just coz of this certificate issue
GeneralRe: still facing issue. please help .. please reply ASAP Pinmembersehariqbal1-Feb-10 6:06 
GeneralRe: still facing issue. please help .. please reply ASAP Pinmemberanarchistic1-Feb-10 8:29 
GeneralRe: still facing issue. please help .. please reply ASAP Pinmembersehariqbal1-Feb-10 22:24 
GeneralRe: still facing issue. please help .. please reply ASAP Pinmemberanarchistic1-Feb-10 22:28 
GeneralRe: still facing issue. please help .. please reply ASAP Pinmembersehariqbal1-Feb-10 22:57 
GeneralGood work. Pinmemberstano13-Nov-09 7:17 
QuestionMessage Encrypted? PinmemberMember 4896705-Nov-09 7:37 
Questionerrhhmm, - simple question; how to consume the service? Pinmembervaerge22-Sep-09 0:08 
AnswerRe: errhhmm, - simple question; how to consume the service? Pinmemberanarchistic22-Sep-09 0:20 
GeneralNeed help on how to access thru browser PinmemberPinna Nageshwar Rao17-Sep-09 5:59 
GeneralRe: Need help on how to access thru browser Pinmemberanarchistic17-Sep-09 6:19 
GeneralRe: Need help on how to access thru browser PinmemberPinna Nageshwar Rao17-Sep-09 20:55 
GeneralRe: Need help on how to access thru browser Pinmemberanarchistic17-Sep-09 22:35 
QuestionIIS vs VS dev server? PinmemberSancho Pancho2-Sep-09 22:50 
Generalthank you ! Pinmemberpetercli23-Jul-09 6:17 
Generalit does not work with pollingDuplexHttpBinding :( Pinmembershapez17-Jul-09 4:21 
GeneralPort # PinmemberJ2kk16-May-09 6:36 
QuestionBasicHttpBinding with TransportwithMessageCredential PinmemberTxu Hevis3-Apr-09 7:48 
AnswerRe: BasicHttpBinding with TransportwithMessageCredential Pinmemberanarchistic4-Apr-09 1:12 
GeneralHelp when host not equal to localhost Pinmembercosmos382405-Mar-09 4:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150331.1 | Last Updated 1 Mar 2008
Article Copyright 2008 by anarchistic
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid