I am trying to embrace the mysteries of SSL communication and have found a great tutorial on this site. I was trying to test my own certificate. Using Visual Studio 2012, I simply added an existing file (my certificate in .pfx format) and then changed the "certificate" and "password" settings in app.config. However, when trying to run it, I got an error:
CryptographicException was unhandled: System cannot find the specified file
Then, I tried the same in my Web Service. There I got some more details about the error:
System.Security.Cryptography.CryptographicException: System cannot find specified file.
at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._QueryCertFileType(String fileName)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags)
v System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
v TestServer.DataService.LoadSoap() v c:\Users\Administrator\Documents\Visual Studio 2012\Projects\TestServer\TestServer\DataService.asmx.cs:line 48
I have written this question to the author of the article, but since his last reply was in March 2012, I am not sure, whether he will reply. If somebody could help me with this problem, I would be very grateful.
P.S.: When exporting the certificate from .cer to .pfx, I have changed the title of the file exported. Although I doubt its effect on the problem, I'd rather mention it.
Did you set the following on the application pool in IIS?
- Go to IIS Manager
- Go to the application pool instance
- Click advanced settings
- Under Process model, set Load User Profile to true
See this stack question for further reading: What exactly happens when I set LoadUserProfile of IIS pool?
For those of you who received the Cryptographic Exception when attempting to import a X509Certificate2 using the Import method, I found that using the Enum option for MachineKeySet bypassed the need for creating a userContext in IIS, and thus easier to implement.
X509Certificate2 cert = new X509Certificate2();
cert.Import(certificateFilePath, certPasshrase,
X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
Because this question has a high search ranking I would like to present a way to present X509Certificate2 with an absolute path (which it only accepts) to a relatively located pxf key file in an ASP.net application.
string path = HttpContext.Current.Server.MapPath("~") + "..\keys\relative_key.pfx";
X509Certificate2 cert = new X509Certificate2(path, "", X509KeyStorageFlags.DefaultKeySet);
By passing CspParameters with flag csdMachineKeyKeyStore IIS can bypass the restriction that throws the Exception.
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = Guid.NewGuid().ToString().ToUpperInvariant();
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cspParams);
I founded solution here:
You need to specify absolute path instead of relative path.
AppDomain.CurrentDomain.BaseDirectory +"/Certificate/cer.PFX"
来源:https://stackoverflow.com/questions/17840825/cryptographicexception-was-unhandled-system-cannot-find-the-specified-file