September, 2011 browsing by month


Use makecert.exe to generate certificates for WCF service in Windows 7/IIS7

Tuesday, September 27th, 2011

-   In order for server certificate to be found by WCF wsHttpBinding’s serviceCertificate, the certificate must be stored in LocalMachine

Notes below describe the process of creating a self-signed certificate, storing in Localmachine, import it to Trusted Root CA, and then use it to sign other certificates to be used for server and client

Generate a self-signed Certificate and Root Trust it


  1. Launch Vs2010 Command Prompt:
    Start -> All Programs -> Visual Studio 2010 -> Visual Studio Tools -> Visual Studio Command Prompt (right click and Run as Administrator)
  2. Create a self-signed (-r), private key exportable (-pe), saving to personal folder (-ss my) under local machine (Local Computer, sr localmachine), named (-n) “YangsoftCA”,common name (-in) “”  with private key file (-sv) as “YangsoftCA.pvk” and public key file “YangsoftCA.cer”Command:

    C:\Windows\system32>makecert -r -pe -ss my -sr LocalMachine -n “CN=YangsoftCA”  -sv  “YangsoftCA.pvk” YangsoftCA.cer

    Password was prompted to secure the private key file

  3.  Open certificate.msc, and this certificate “YangsoftCA” appear under Local Computer / Personal store:

    Certificates under Certmngr.msc

    Figure 1 Certificate created by makecert.exe appears under Local Computer/Personal folder

  4. We intended to use this certificate as root level certificate authority so it can be used to issue chain trusted certificates for encrypting communications between server and client, as well as authenticating web clients that are going to access the WCF service hosted on the server. At this point, when I double clicked on the certificate and opened up the property window, it said that the certificate authority was not trusted, as shown in Figure 2:

    Certificate not root trusted

    Figure 2 MMC - certificate not yet trusted

  5. To make this certificate the root of the trust chain, imported the YangsoftCA.cer file into the Trusted Root Certificate Authorities store (right-clicked on the certificate, copied and then pasted into Trusted Root Certificate Authorities) ; once I did that, now when I went back to the personal store and opened the “YangsoftCA” certificate, the status changed to “OK”, as shown in Figure 3.

    Certificate root trusted

    Figure 3 Certificate imported to Root Trusted CA

  6. Now, I can use it to issue other certificates down the trust chain.

Use the Root Trusted Certificate to Issue Chain Trusted Certificates

First, used the YangsoftCA to sign a certificate to be used on server-side; as it is to be used for the server where WCF service is to be hosted, the signed-certificate needed to be saved into local computer:


C:\Windows\system32>makecert -n “CN=SignedByYangsoftCA” -iv “YangsoftCA.pvk” -ic “YangsoftCA.cer” -pe -ss my -sr localmachine -sv “SignedByYangsoftCA.pvk” SignedByYangsoftCA.cer

Explanation of switches:

  1. The order of switches does not matter
  2. –iv and -ic: we used the private and public key files of the Root Trusted CA, “YangsoftCA” to sign this certificate
  3. –pe: make this new certificate’ private key exportable, which is saved to the file specified in –sv, “SignedByYangsoftCA.pvk”
  4. –sv: private key file of this certificate
  5. –ss: store name my=Personal
  6. –sr: store location, if not specified, it will go to “Current User” which we do not want in this case.
  7. Certificate file (or public key file): SignedByYangsoftCA.cer
  8. When this command was run, there were several prompts to enter password. First prompt was for Subject’s password (that is to protect file “SignedbyYangsoftCA.pvk”), the last prompt was for “Issuer”, which was needed to use the Issuer’s private key file, in this case, the “YangsoftCA.pvk”.

Where did it end up?

Opened the Certificates MMC, under Local Computer/Personal store, now we see “SignedByYangsoftCA”. Double click it and we can see the certificate shows as the sub level certificate under the certification path, as shown in Figure 4:

Certificate signed by Root Trusted CA

Figure 4 Certificate signed by root trusted certificate (YangsoftCA)

Assign the Certificate Signed by Root CA to Website

Now, let’s assign this certificate to the website that hosts the WCF service. There are two ways to do this. First, we can assign the server-side certificate via system.serviceModelsection in the web.config of WCF Service application, as shown in text box below:



<behavior name=”SvcBehavior”>

<serviceMetadata  httpsGetEnabled=”true” httpGetEnabled=”false”/>



<serviceCertificate findValue=”SignedByYangsoftCA” storeLocation=”LocalMachine” storeName=”My” x509FindType=”FindBySubjectName”/>


<authentication certificateValidationMode=”PeerOrChainTrust”  />



<!–this line turned on logging server error that is not thrown to EventLog. Use EventVwr/Application to find more details of the behind scene error; but make sure to turn this off after debugging is done since it will impact performance–>

<serviceSecurityAudit auditLogLocation=”Application” serviceAuthorizationAuditLevel=”Failure” messageAuthenticationAuditLevel=”Failure” suppressAuditFailure=”true” />





We can also install the SignedByYangsoftCA certificate to IIS and assign to the website through IIS7. In order for the certificate to be imported to IIS7, we first need to merge the private and public key files of the certificate into a single .pfx file that IIS7 is willing to receive.

Return to c:\windows\system32  and type these commands:

pvk2pfx  -pvk SignedByYangsoftCA.pvk –spc SignedByYangsoftCA.cer –pfx SignedByYangsoftCA.pfx

This merged the .pvk and .cer files into an exchangeable pfx file that can be imported to IIS7.

Install Certificate “SignedByYangsoftCA” to IIS localmachine.

  1. Start IIS7 -> Click on root folder Localhost node
  2. Double-click on Server Certificates then select “Import” from the “Action” pane to the right.
  3. Browse to c:\windows\System32\SignedByYangsoftCA.pfx; there is a place to enter password, but ignore it as this is not the password used to protect the private key file. Imported successfully.
  4. Now, go to the website where I want to assign the server certificate, click on Bindings, highlight the binding and click on Edit
  5. You can see now the “SignedByYangsoftCA” certificate is showing in the certificates dropdown list; select it and done, Figure 5.

    Bind Certificate to website, IIS7

    Figure 5 Binding certificate to website, IIS7

Now that the certificate is assigned, you can remove theentry from the web.config file of the WCF service app and the service should still render to https without problem.

Client Certificate

  1. Configure IIS7 to require client to have a certificate to access the WCF service:
    1. Open IIS7 and drill down to the virtual folder where the WCF service is published, in this case, “Demo” directory
    2. Double click on SSL Settings (on Feature View)
    3. Check the “Require Client Certificate” and Apply.

    Before a client certificate was issued, I tried to browse to the .svc file and the browser returned this message, as shown in Figure 6:

    Client certificate error

    Figure 6 If IIS7 Require Client Certificate is checked, this is client side error

  2. Now, let’s use the YangsoftCA that is already in the Root Trusted CA to issue a client certificate and then export as PFX file.Command:C:\Windows\system32>makecert -n “CN=ClientByYangsoftCA” -ss my -pe -sv “ClientBy
    YangsoftCA.pvk” -iv “YangsoftCA.pvk” -ic “YangsoftCA.cer” ClientByYangsoftCA.cer
    Explanation: generated a certificate signed (issued) by root trusted CA, “YangsoftCA”, named “ClientByYangsoftCA”, saved to CurrentUser/Personal Store, and exported private key file “ClientByYangsoftCA.pvk”.
  3. Then merged the private key and public key files into one PFX file:C:\Windows\system32>pvk2pfx -pvk ClientByYangsoftCA.pvk -spc ClientByYangsoftCA.
    cer -pfx ClientByYangsoftCA.pfx
  4. Browsed the ClientByYangsoftCA.pfx file and double clicked it, Certificate Import wizard popped up; followed the screen instruction, but ignore the password. I thought this password was the password used in protecting the private key file but when I entered it, it rejected; then I entered no password, and it took it. Is this a bug of what?

Client Certificate error – Keyset does not exist

Thursday, September 8th, 2011

A web client with Certificate called a WCF service hosted in a local machine (in development phase), secured with server-side certificate (SSL or Https:) and returned this overly simple but convoluted error, “Keyset does not exist“. What’s going on?

Well, after some readings returned from Google search, especially grateful to this two posts and, this turned out to be that the “Network Service” account, which was used by the WCF service to access the resource at hosting server (even though it is just my local machine, a Windows 2003 server) did not have any permission to the private key stored in the server. That’s why the name “Keyset” – since the web client certificate only sent in a Public key and it has to matched the private key stored in the web server. So, my goal was to find the private key for this client certificate and give read permission to the “Network Service” account.

Finding the FindPrivateKey.exe was a challenge on it self, as it turned out. There might be other way to get it, but I ended up having to download a 17 MB WCF_WF sample codes package, opened the solution FindPrivateKey.sln in somewhere deep in the package and compiled it, then ran the executable using “thumbprint” switch, as shown below:

DirectoryWhereFileIsLocated>FindPrivateKey My LocalMachine -t “af 50 4e f4 3b 57 ea f0 26 a8 b0 35 bf a7 0a a7 87 ef 10 5b” -a

And it returned:
C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Ma

So I went into that private key file and grant read permission to “Network Service” account; after that, I went back to the web client application, and assign the client certificate using X509FindType.FindByThumbprint option (use the thumbprint value above af 50 4e f4 3b 57 ea f0 26 a8 b0 35 bf a7 0a a7 87 ef 10 5b without spaces). Now the error disappeared and the WCF service proxy class returned to working condition.

Where to find FindPrivateKey.exe?

Thursday, September 8th, 2011

From a somewhat obscure blog here, I found the source code and compiled it myself. As it turned out, this was included in a huge WCF and WF Samples download at When it was unzipped, there were over 1200 files extracted! After that, went into folder: W:\Development\Downloads\Microsoft\WF_WCF_Samples\WCF\Setup\FindPrivateKey\CS, opened FindPrivateKey.sln and compiled it.

Then I went into the bin folder and run it like this :

DirectoryWhereFileIsLocated>FindPrivateKey My LocalMachine -t “af 50 4e f4 3b 57 ea f0 26 a8 b0 35 bf a7 0a a7 87 ef 10 5b” -a

And it returned:
C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Ma

Explanations of switches:

t=find by thumbprint

a=Outputs the absolute file name

Get examples of how to use FindPrivateKey from here

Request and install client certificate – Windows 2003 server

Tuesday, September 6th, 2011

Last post was about how to request and install a server-side certificate in preparation for authenticating WCF service client using client certificate. Once the server-side certificate is in place, it’s time to get the client certificate in order. Here were the steps I took a few days ago for requesting, issuing and installing a client certificate in a Windows 2003 server machine:

  1. Went to Http://localhost:8080/CertSrv – >Request a certificate ->Browser certificate
  2. Submiited the request by following on-screen instruction (entered Name, e-mail, Company, department and chose key strength, 2048)
  3. Went into CA (Start->Administrative tools -> Certificate Authority ->Pending requests folder
  4. All tasks -> Issue and issued the client or browser certificate.
  5. Went into Issued Certificates folder and double clicked on the certificate request item ->Details – >Copy to file, the “Welcome to the Certificate Export
    wizard” pop up, Next and chose “Based-64 encoded X.509 (.Cer) option, same as the server-side cert created previously, Next
  6. Copied to c:\ClientCert.cer, Next and “Completing the Certificate Export wizard” showing “File Name, Export Keys (No), Include all certificates in the certification path (No), File format (base64-coded X.509)”, Finish
  7. Went into c:\ClientCert.cer and double clicked to open the Certificate – >Install certificate – >Next – >”Automatically select a certificate store,..” -> Next -> Finish

Request, Issue and Install a server-side certificate – Windows 2003 server/IIS6

Tuesday, September 6th, 2011

To use client certificates for authentication, first need to install a server-side certificate. The steps here were what I took to Request, Issue and Installed a server-side certificate for certificate auhtentication with Microsoft certificate Services and IIS6 in Windows 2003 environment:

  1. IIS6->Websites->Default website (at this point, verify the CertSrv is shown in as a Virtual directory under this site) – > Right click on Default website node and selected Properties ->Directory Security ->Server Certificate.
  2. If there is no certificate already installed on the server, click on Create New Certificate; as I already had certificates installed on my local machine, the only options at this point are “Renew the Current certificate”, “Remove the current certificate”,”Replace the current certificate”, “Export the current certificate to a .pfx file”, and “Copy or Move the current certificate to a remove server site”.
  3. For this project, I chose “Renew the current certificate“, and next
  4. Chose “Prepare the request now, but send it later” (default option) and next.
  5. Certificate request file name: leave as default at c:\certreq.txt
  6. Open the c:\certreq.txt file and copied the content to clipboard.The content is a big chunk of mumble-jumble ASCII letters like these: “—–BEGIN NEW CERTIFICATE REQUEST—–MIIDTDCCArUCAQAwcTELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0Zsb3JpZGExDjAM
  7. Now I went to http://localhost:8080/CertSrv and a page titled Microsoft Certificate Service came up (I had trouble to open this page from http://localhost/CertSrv initially but then realized my default website is not in http://localhost; rather my default website is configured to run from port 8080 instead of the default 80).
  8. Click on Request a certificate and select submit an advanced certificate request on next page
  9. There are two options on next page: “Create and submit a request to this CA.” and
    Submit a certificate request by using a base-64-encoded CMC or PKCS #10 file, or submit a renewal request by using a base-64-encoded PKCS #7 file. “, selected the second one.
  10. Now paste the content from clipboard to the Base-64-encoded certificate request (CMC or PKCS #10 or PKCS #7) textarea or I could use the “Browse for a file to insert” feature. Then clicked Submit
  11. If submitted successfully, the next screen said, “Your certificate request has been received. However, you must wait for an administator to issue the certificate you requested..Please return to this web site in a day or two to retrieve your certificate.”
  12. Now I went to the CA MMC (Start – >Administrative Tools -> Certificate Authority) and I saw the request sitting under the “Pending Requests” folder. I right clicked on the request and Issued it (All Tasks -> Issue) and the request moved to Issued Certificates” folder
  13. Next step was to copy certifcate to a .cer file. To do that, double clicked on the Requested certificate to view it, clicked on Details tab and Copy to a file. On “Export File Format” selected the “Base-64 encoded X.509 (.Cer) and saved to “c:\ServerCertificate.cer”
  14. Now I went into IIS6 ->Default website->Properties ->Directory Security -> Server Certificate ->Next – > select “Process the pending request and install the certificate” and opend the “c:\ServerCertificate.cer” file from “Process a Pending reqeust” screen
  15. Next screen asking about “SSL” port, leave it as default 444 and clicked Next, Next and Finish.

To verify that the server-side certificate was installed successfully, I went back to IIS6, picked a virtual directory, for example, “WcfSecure” and open “Properties” window->Directory Security->Edit (Under Secure Communication) and checked “Required secure channel (SSL), and for client certificates, selected “Accept client certificates” for now; then I browsed to a .svc file without https, such as http://localhost:8080/WcfSecured/Demo.svc; at this point I got browser error message asking me to add https to the address; so I changed to https://localhost:8080/WcfSecured/Demo.svc (or can be demo.aspx or demo.ashx page), and as expected, now the page showed correctly. That confirmed that the server-side certificate had been installed correctly. Next is to request and issue a client certificate so we can authenticate WCF Service client.