Before anyone flags this as duplicate from the other barrel full of questions about WCF, I don't want MSDN links and blog article references. I can Google for myself, and have been at this for 3 days, so if all you have are Google links, please abstain.
I'm having a heck of a time with an IIS hosted WCF service using wsHttpBinding and a custom password authenticator. IIS is working fine for my standard ASPX and WCF non-secure services (using wsHttpBinding with security mode="None", but trying security mode="Message" or "Transport" requires an SSL certificate in the mix. I am to the point that I'm getting this error:
"The certificate 'CN=SignedByCA' must have a private key that is capable of key exchange. The process must have access rights for the private key."
By my research, either the service hosting my WCF service cannot access the private key file of my certificate, or I didn't generate the certificate correctly.
I generated the keys using:
makecert -n "CN=TempCA" -r -sv TempCA.pvk TempCA.cer
makecert -sk SignedByCA -iv TempCA.pvk -n "CN=SignedByCA" -ic TempCA.cer SignedByCA.cer -sr currentuser -ss My
I then imported the TempCA cert into my Trusted Root Certification Authority store, and I imported the SignedByCA.cer into my "Personal" store of the Local Computer. WCF can now see the certificate, but the above error indicates something either permissions problem or a key problem. I tried importing the cert into IIS Admin Service's Personal store as well, no luck.
By the way, I've added this to my web.config for the service:
<serviceCertificate
findValue="...."
x509FindType="FindByThumbprint"
storeLocation="LocalMachine"
storeName="My"
/>
I get the error from my client project when I add / update the service reference.
From my research, on Windows 7 I should be able to use the Certificate Manager and right click on the certificate in the MMC snapin and choose All Tasks -> Manage Private Key.. or some such. When I right click the certificate, I do not see that option, I only have these options under All Tasks: [Open, Request Certificate With New Key, Renew Certificate With New Key, Export...] This leads me to believe it is a cert problem and not a priv problem.
Thanks in advance.
After regenerating a .PFX file (PKCS #12 Certificate) http://msdn.microsoft.com/en-us/library/ms867088.aspx (create a .spc file with cert2spc.exe and a .pfx file with pvk2pfx.exe) and loading the .pfx file into the Certificate store, this exposes the "Manage Private Key" option. The original problem was following the MSDN instructions blindly and using a .CER public certificate file, which was not adequate for key exchange. The .PFX file does the trick. Now I'm able to add permissions for users / services to Read the key.
I also found that IIS7 on Windows7 was not running under the normal documented identity "NETWORK SERVICE" or "LOCAL SERVICE" but was running under "ApplicationPoolIdentity". So after I switched the identity, that issue resolved, (just another annoyance in getting WCF off the ground).
Related
When wcf service will use the certificate, then how the client, which will consume the wcf service will send the certificate to a wcf service. This idea is not clear to me that when wcf client will call wcf service first time, then how the client will send a certificate of service? Please discuss how people work with wcf & certificate.
Also guide me briefly that what are the steps we need to do to attach certificate with our wcf service?
How wcf client can send the certificate to wcf service when they make a call?
Do we need at all anything to configure for the certificate at wcf client end?
One guy told me
When use the certificate authentication in the wcf, then in the serive side and client side, you will need to install the service certificate and the client certificate. Then in the client side, the client will use the service public key to encrypt the message and send to the service, then the service will use the service private key to decrypt the message. And in the service side, it will use the the client public key to encrypt the message and send to the client. Then the client will use the client private key to decrypt the message.
if this is the limitation of certificate authentication that we need to install a certificate on both end, then we can use certificate authentication in very limited case. any tell me how to use certificate authentication when we have no control over the client who will consume the service.
when client is unknown they how they can send the certificate to our service.
actually i am trying to know how people manage to implement certificate authentication in real life when they do not have a control over the client who will be using their service. thanks
OK, you're looking for client certificate authentication of your would-be clients, which always includes SSL.
I've got a couple links for you to check out:
http://msdn.microsoft.com/en-us/library/ms731074(v=vs.110).aspx is the official version from MS that has good information, but not necessarily good instructions on getting this working.
and
http://architecturebyashwani.blogspot.de/2010/01/wcf-client-authentication-using-x509.html ... this is a better source in my opinion because it will walk you through the process of setting it up the certificates (self signed) you'll need for testing.
As far as controlling the issuance and certificates to client computers, that can be easy or difficult depending on how many client devices are involved and where they're located.
If you're talking about an internal implementation for server-to-server communication within a network, or perhaps a few PCs connecting to the host, that's not too difficult. In a nutshell, you copy a .PFX file (cert and private key) to the clients and host and set them up in the cert store (Like LocalComputer\Trusted, for instance). Then you set up the client and host WCF software to a) access the certificates and b) make get the host to deny access to non-authenticated users.
However, if you're talking about issuing and managing certificates for a thousand people walking around with iPhones, Androids and Laptops, that's a much more difficult proposition to control.
Here's a link, though, on setting up an internal certificate authority:
http://technet.microsoft.com/en-us/library/ff849263(v=ws.10).aspx
Added: This DOS scripting will create client auth certs, package them as a PFX and install them into a certificate store on the host.
On the host side you do this:
rem Comment -- creates client authentication cert, puts it in the currentuser\root authority and signs it based on the other certificate
makecert.exe -n cn=ClientAuthCert ClientAuthCert.cer -is root -sky exchange -pe -sv ClientAuthCert.pvk -eku 1.3.6.1.5.5.7.3.2
rem Comment -- make the pfx file that will allow you to copy certs around with private keys
pvk2pfx -pvk ClientAuthCert.pvk -spc ClientAuthCert.cer -pfx ClientAuthCert.pfx -f
rem Comment -- installs the certificate on the host in the localmachine / trusted people store
certmgr.exe -add ClientAuthCert.cer -c -s -r LocalMachine TrustedPeople
On the client side, you do this (after copying the .CER and .PFX files over to the client machine):
rem comment -- these lines install the certificates in the stores on the client device
certmgr.exe -add ClientAuthCert.cer -c -s -r LocalMachine TrustedPeople
Certmgr.exe -add ClientAuthCert.pfx -c -s -r CurrentUser My
I am in a process of generating an SSL cert for a domain name.
What I have done:
Went to the IIS management > Server Certificates and clicked on Create Request. This generated a *.com file with a hash inside it that I submitted to the GoDaddy.
From GoDaddy I got back a zip with two files: *.crt and *.p7b
I exported the certificate to a *.cer file and uploaded it to Azure, but when I try to deploy the cloud project I get an error:
Certificate with thumbprint associated with HTTPS input endpoint
does not contain private key
After reading similar issues on the Internet, I understand that my *.cer file doesnt contain the private key.
My problem is that no matter how I try to export it to a *.PFX, the PFX option is always disabled in the cert export wizard.
Also not sure if it is related, but when I Click on Complete Certificate Request in IIS and select the cert that I got from GoDaddy. I get an error:
Cannot find the certificate request that is associated with this
certificate file. A certificate request must be completed on the
computer where the request was created.
You will not have the option of exporting from IIS or exporting to PFX from Certificate Manager if you do not do the IIS "Create Certificate Request" and "Complete Certificate Request" from the same machine.
That was my problem. I did these two steps from two different machines.
I had to create a new request (in IIS), go to GoDaddy, rekey my certificate, download the new certificate, and then complete the request (in IIS).
This turned out to be something completely idiotic, as usual messed up by Microsoft.
The process of creating a cert for a domain is that you need to use [Create Certificate Request] in IIS.
Then send the created hash to the Authority and use the [Complete Certificate Request] in IIS where you provide the cert given to you by the Authority. This will install the cert into your local IIS
After the cert is installed you need to right click on it and do an export to a *.PFX file. The PFX file now can be uploaded to Azure or any other hosting...
The processes could have been very simple, if Microsoft didn't make sure to screw it up.
The thing is that when you click on [Complete Certificate Request], the file open dialog has a file type of *.CER, but this is wrong because you need to provide *.CRT!!! The solution is to change the file type select to All Files *.* and chose the *.CRT file provided by the Authority.
I am writing a WCF service where I need to access the Hash Code of client certificates that are used to connect to the service.
I am looking for a property or method similar to Request.ClientCertificate from ASP.NET 2.0 days but cannot find anything that allows easy access to the client certificate.
Our service is set up such that it is running with SSL using basicHttpBinding and security mode of "Transport".
IIS has been set up to Require SSL and Accept certificates.
One thing to note is that our server certificate used to secure the endpoint is from a different CA to that of the client certificates - the client certificates are intended to be validated solely through custom code (thus the need to get the hash code of a connecting certificate).
I have created a custom implementation of the IDispatchMessageInspector to see if there is any access to a client certificate from there but to no avail.
Has anyone attempted this and had success before?
Looks like what the best option for you would be to implement a custom Certificate Validator for your service. This is basically a class that derives from X509CertificateValidator and is then registered through the config file.
There's more complete information on how to do this on this article.
For reference if anyone else attempts to apply client certificate authentication the following steps were required to get it to work (we are using basicHttpBinding within WCF for this instance and running in a local instance of IIS):
Set up IIS to use a HTTPS binding for the site and secure this in IIS with a server certificate
Within IIS change the SSL Settings for your site to Require SSL and Require client certificates (It must be Require - Accept will not work)
Within the WCF configuration ammend the basicHttpBinding and set security mode to "Transport" and the transport clientCredentialType to "Certificate"
Ensure that the root certificate (the one used to create any client certificates) is within the "Trusted Root Cerrtification Authorities" for the Local Computer on which IIS is running.
NOTE If you are in a development environment you may need to generate your own root certificate, the makecert command line application is very useful for this; simply run the following command:
makecert -n "CN=My Test Auth" -r -cy authority -a sha1 -sv "My Private Key.pvk" TestAuth.cer
This creates a certificate called TestAuth.cer (which needs to be added to the Computer's "Trusted Root Cerrtification Authorities") and a private key file called "My Private Key.pvk".
Now to generate a client certificate you can run this command:
makecert -a sha1 -n "CN=myConnectionCert" -ic "TestAuth.cer" -iv "My Private Key.pvk" -ss My
This created a certificate with a subject of myConnectionCert and adds it to your personal certificate store - when you now access the site (to view the service page for example) IE should prompt you to select the certificate - chose the one you have just created and you should see the service page as normal.
I need to secure a WCF service that uses netTcpBinding and connects directly with a Windows Forms based application. I only need it to be secured at the transport layer.
I'm pretty sure that I have it working locally, i.e. I can run the service locally, and connect to it with the client.
When I try to setup the service so that it is running on a server as opposed to my local machine, I'm having certificate issues. The error log says that the certificate must have a private key that is capable of key exchange and that the process must have access rights for the private key.
I'm using a development certificate created using makecert.
makecert -n "CN=MY COMPANY DEBUG" -pe -sky exchange Debug.cer
I must admit that I'm very new to using certificates. Does anyone have any pointers on how I can fix this, or a better way to use a certificate to add transport security to a WCF service using netTcpBinding?
Thanks.
Try this:
makecert -n "CN=MY COMPANY DEBUG" -pe -sky exchange Debug.cer -sv Debug.pvk
pvk2pfx -pvk Debug.pvk -spc Debug.cer -pfx Debug.pfx
You will then end up with three files, the .cer file (public key), the .pvk (private key), and the .pfx (key exchange with both). You can then install the .pfx file on the server like so:
certutil -p "" -importPFX Certificates\Debug.pfx
At the client end, you only need to install the .cer file. These installs (.cer and .pfx above) you can also do through the Certificates MMC snap-in (Start, Run, MMC.exe, then add the Certificates snap-in for the current machine).
Read this (covers https case but still may help) and this.
Since we are talking about transport-level security, I don't think your server process should know anything about certificate you are using to provide it.
I am creating a WCF service hosted within IIS7 on Windows Vista SP1. I am getting the following error:
The certificate 'CN=SignedByLocalHost' must have a private key that is capable of key exchange. The process must have access rights for the private key.
It looks like I would need to give the host process assess to the certificate which was done in the past with winhttpcertcfg which has been deprecated for Vista. The article I found indicates to use the certificate console, but I am missing somethign because I don't see any capability to edit my cert.
Any help would be great!
Thanks
Figured it out.
Assuming you have a self signed cert at c:\OutCert the following command will work. I had left off the -sky exchange.
makecert -sk SignedByCA -iv c:\OutCert.pvk -n "CN=MyLocalHost" -ic c:\OutCert.cer -sr LocalMachine -ss My -sky exchange pe
Now you can go into the MMC tool and manage the private keys and grant IIS access to the key. To manage private keys, right-click on the certificate and select All Tasks / Manage Private Keys.
You can use IIS 7.0/7.5
Just Start->Run ->inetmgr
Select the server
Under "Security" panel, go to "Server Certificates"
In the left pane click - "Create Self Signed Certificate" and complete the process
The crtfiticate will get installed in LocalMachine StoreLocation under Personal storename.
Now use this certificate in your WCF service and you will not face this error