I am currently trying to access a service provided by a 3rd party. They have issued us a certificate in PKCS format. The certificate is installed in Local computer - Trusted root directory.
Our application at run time finds this certificate and sends it to the authentication URL hosted by the 3rd party, where it is authenticated and the SAML tokens are issued. This is then used to call the actual service that does the functionality we desire.
when I run my application consuming this service via the service reference in the development machine [Windows 7] everything works smoothly.
Now the pain point is since we have a Citrix environment where the testing would take place, we get an error as
Exception in METHOD: SOAP security negotiation with "Service URL" for
target failed. Inner Exception:
System.Security.Cryptography.CryptographicException: Keyset does not
exist.
Can any one help me in resolving this issue, as am unable to reproduce it my local and it happens only in the server OS, am not sure if its an issue with privileges or some code issue.
There are two likely causes of this issue:
The certificate does not have a private key.
The user your process runs as does not have permissions to read the private key.
As you already have this up & running in your development environment, lets assume the cause is 2.
If you don't know it already, you need to determine the user account that your process runs as on your test server. Then open MMC on the test server and add the Certificates snap-in. Find the certificate, right-click and choose All Tasks | Manage Private Keys... and grant read access to the user.
Read lots more about this at:
X509Certificate - Keyset does not exist
CryptographicException 'Keyset does not exist', but only through WCF
Service failure with CryptographicException – Keyset does not exist
Wcf: Keyset does not exist
Thanks for the information. The root cause for this issue was permission issue for the certificate. Since the certificate was installed in the server with Admin privileges, the permission had to be given to all the users for accessing the certificate.
Related
I have a worker role which uses the Third party WCF services, the developers of WCF services told me to add two certificates on my Azure Trusted Root store, for authentication.
When I am trying to add the same via certificates tab in roles --> properties, it is not allowed.
So I come to a solution, where I write a code in console application along with these two certificates (.cer files). When the worker role executes, it adds these certificates on desired storename i.e. LocalMachine--> TrustedRoot.
However still my application is throwing error saying "Keyset does not exist"
I have checked through RDP, and found that the cer files are already installed on this location.
Also, I am trying to find the Private Key, but unable to do so, I think this is because these are ".cer" files.
The problem is that your files are .cer which do not store private key. One of these certificates (leaf, or authentication certificate) must be in a PFX. Commonly they have .pfx or .p12 extension.
In my ASP.NET application I'm loading a certificate from the certificate store:
var myCert = CertificateUtils.GetCertificate("thumbprint");
This certificate contains a key pair which is used to decrypt the encrypted application settings.
The certificate is installed in Personal certificate store under the Local Computer. It works well when the application is running under the IIS Express. But if I execute it under the full IIS Web Server, the myCert instance is missing the private key.
The PrivateKey field of myCert object contains an exception:
'myCert.PrivateKey' threw an exception of type 'System.Security.Cryptography.CryptographicException'
I have checked that other fields of myCert object contain same values (like, for example, certificate serial number, thumbprint or expiration), so it seems it's getting the same certificate under both IIS and IIS Express. Only the private key is missing in the case of full IIS.
The only thing I have changed was the Local Development Server in project's properties ("Use IIE Express" / "Use IIS Web Server"). It's running inside the Azure Emulator Express in both cases.
Does anyone have an idea, why is this happenning?
Running on IIS Express, the program uses your credentials to access the certificate, while on IIS the pool identity's credentials are used. You can easily check the certificate ACL to see who is allowed or not.
Follow these steps:
Check what Application Pool your web site uses
Open Internet Information Services Manager, select Sites in the Connections tree on the left. Select your site in the middle panel and click Basic settings under Actions on the right panel.
Check what identity the Application Pool uses
Select Application Pools in the Connections tree on the left and find the identity in the middle panel. It'll be probably "NETWORK SERVICE".
Add read permissions for the identity used by Application Pool to your certificate
Open the Microsoft Management Console (mmc), add the Certificates snap-in for local Computer account and find your certificate under Personal certificates. Open its context menu, All Tasks and Manage Private Keys.... Click Add.., enter the identity ("NETWORK SERVICE") and click Check Names and OK. Under Permissions for allow only the Read permission.
You can read details in this question: How to give ASP.NET access to a private key in a certificate in the certificate store?
I was having this problem to debug the application ".PrivateKey' threw an exception of type 'System.Security.Cryptography.CryptographicException"
I solve like this:
In mmc > Local Computer > Personal > Certificate > right click on certificate > All Tasks > Manage Private Keys:
Add "everyone" user and select Total Control.
I'm trying to connect to a service that a 3rd party company is publishing. For the authentication part, we use two certificates, one with a public key and one with a private key.
I've made an console application just to test the certificates in differente stores, with the following possibilities:
Location: Current User; Store: Personal
Location: Local Machine; Store: Personal (installed with admin user. I don't have admin permissions)
It was working until I've changed my computer to another this week. I've tested on other machines and it's working on both configurations. But mine only works when I try the 'Current User Location'. Why? My application needs to use the 'Local Machine Location'.
The only possibility I can think about is some kind of permission. But I'm not finding any clue on web. All the similar links say something about the bindings, wrong certificates, overriding ServiceCallBack, etc.
Someone knows if any permission is needed to use the certificate from LocalMachine?
Obs: the application can find the certificate, but when it uses I got the following error:
Could not establish trust relationship for the SSL/TLS secure channel with authority 'name-of-certificate'
Note: I know there is other posts similar to this, but the problem/scenario is really different.
Possibly the identity of the application pool has to rights to read the private key of the certificate from the Local Machine store.
To add the permission, go to the Certificate snapin, right click the certificate, select All Tasks and Manage private keys. From there, add the application pool identity.
Also, as always, make sure that the application pool's "Load user profile" setting is set to true.
I'm trying to write a C# client that consumes a web service. The communication is encrypted. I have downloaded and installed the sites' certificate into that magic place where WinXP keeps them.
When I run my client I fail with "The remote certificate is invalid according to the validation procedure."
When I run certmgr.msc, the GUI informs me that the certificate has an invalid policy. The certificate has valid dates and the certification path is ok. The certificate does have a certificate policy with a policy identify integers interleaved with dots (like 1.2.30...)
Using code from the X509Certificate2.Verify Method documentation, I can see that the Verify message does indeed return false.
In trying to research this error, I found a reference in Brian Komar's Windows Server 2008 PKI and Certificate Security:
Policy validation. If the application that calls the certificate chaining engine expects a specific application policy or certificate OIDs in the certificate, and the required policy or OIDs are not contained within the certificates in the CA chain, the certificate chaining engine considers the certificate to be invalid.
I don't see that I'm setting any expectation of a specific application policy. I'm in the process of porting this WSE3 code to WCF so perhaps it is built in.
Any advice on how to run this down further? Is there really a problem with the certificate?
If the certificate is ok, do I need to configure or extend the CryptoConfig class to turn off checking the policy?
Any and all help appreciated.
You can always disable the validation by setting the ServicePointManager..::.ServerCertificateValidationCallback to a delegate returning true. This would give you time to track down any issues with the certificate.
One technique I've used to track these type of errors down is to visit the Web Service in a browser.
For example, if you have a Web Service at https://server/foo.asmx, drop that address into the browser of your choice, and you may get a more human readable interpretation of the error.
We've been working a lot in an application developed in VS 2010, C#, and WCF. We use Transport as the security mode, and in the TransportSecurity Properties set to None and None.
We are hosting the service in IIS6. After working a lot we managed to make it work using https. The Certificate we used was a self created one, created with the selfssl.exe tool. After creating the Certificate and storing it in the "Trusted Certificates" list, we set it as the Server Certificate in IIS for our Site, and also do the "binding" between the Certificate Thumbprint and the localhost address with the 443 port, using the httpcfg tool.
Well, we also use the famous piece of code not recommended for production (we are aware of that) that enables the validation of a Certificate that is not issued by a valid Certification Authority. This piece of code we took it from the MSDN WCF Hands On Lab. In this piece of code we give it the CN=NAME of the certificate and it works.
Ok, we finally got it to work. This was all in development. Now we are in the testing stage and they agreed to use the piece of code that enables the certificate. The problem is that the Certificate that we need to use, after setting it in the IIS and setting it to use the famous piece of code, it doesn't work.
The error we get is this one (only showing the first part of the error and not the stack trace):
System.ServiceModel.Security.SecurityNegotiationException: Could not establish trust relationship for the SSL/TLS secure channel with authority '172.30.224.46'. ---> System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
The new Certificate is issued by their own Certification Authority, and it has several differences in comparison with our Self-Generated one, for example the "Usage" properties are different, or for example our Certificate has a "Enhanced Usage" property and theirs don't.
The other great difference we notice in the Certificate is that theirs is part of a hierarchy of Certificates, where they have a Trusted Root Certificate, then an Intermediate Certification Authoity and the Certificate to use in the Server is under that Intermediate one.
Is a special configuration needed to support this kind of certificates that are part of a hierachy? What can you guys tell us about this? .... we need some help :S
We also made a test creating a Self-Signed Certificate and all the steps needed to set it up in their environment, and the application works.
Thanks for your help and attention,
Andrey Gonzalez
Usually you get this error when the server name stored in the certificate is different from the hostname you use on the client to refer to the server.
For example, your server certificate is issued for "yourserver.com" and you are trying to access it from the client using only "yourserver" or its IP address.