104

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.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Storm
  • 3,062
  • 4
  • 23
  • 54
  • 2
    Are you specifying the full path name to the file? – gtrig Jul 24 '13 at 17:32
  • 1
    Wow... now I feel like a complete idiot. After specifying full path, it works... well, the client says, that the certificate is not valid, but that's probably because it was issued for my old computer. So, thank you... I think, this topic can be closed as non-constructive. – Storm Jul 24 '13 at 17:43
  • 1
    For same issue in Azure app service - [Certenroll on Azure - Generating self signed certificates](https://stackoverflow.com/q/58800004/465053) – RBT Nov 22 '21 at 09:40

7 Answers7

316

Did you set the following on the application pool in IIS?

  1. Go to IIS Manager
  2. Go to the application pool instance
  3. Click advanced settings
  4. 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?

Community
  • 1
  • 1
nologo
  • 5,918
  • 3
  • 36
  • 50
  • 1
    http://stackoverflow.com/questions/17149132/what-exactly-happens-when-i-set-loaduserprofile-of-iis-pool – nologo Mar 10 '16 at 00:52
  • Thank you sir! I've been struggling with this error for months. Having to restart the server or restarting the IIS in order to 'have time' before the error started appearing all over again. – Miquel Coll Mar 14 '16 at 13:53
  • 4
    Oh my god. What an absurd error!! I tried checking and checking and couldn't find anything wrong with the file name. ***t cryptography exception telling about wrong file path while in fact it is not – Hoàng Long Mar 15 '16 at 03:53
  • if this does not work for you , just double check that you are setting this to true on right application pool.(first check which app pool is assigned to your app) – Iman May 07 '19 at 05:37
  • `var key = CngKey.Import(Convert.FromBase64String(secretKey), CngKeyBlobFormat.Pkcs8PrivateBlob); ` I was loading a private key (from a base64 string, no path) and got this error. The answer saved my days!! Thank you – Matteo Gaggiano Sep 10 '20 at 18:35
  • 4
    In Azure: Use Application Settings -> Add "WEBSITE_LOAD_USER_PROFILE" with a value of "1". – hanzolo Sep 30 '20 at 19:22
  • 1
    Just wanted to add to this that (1) my app was a .NET 6 + Angular app, (2) 'specifying the full path name to the file' had zero beneficial impact (location/name is specified in appsettings.json), and (3) I'm working with a hosting site and this particular IIS setting couldn't be viewed or set in the Control Panel provided. The support staff person had to make the IIS setting update, and the result was: the pfx cert is correctly processed. – StackOverflowUser Sep 19 '22 at 07:08
  • Good thing I found this one. I was working on a .NET 7 app and the absurdity is that I thought it was due to file path so I loaded the file myself and pass a **byte array** to the Import method. No error on local dev environment as well. On server, the Stack Trace points exactly to the `Import` method which is absurd because surely the file was loaded into a byte array. That was when I knew it wasn't about actual file path because the key file was actually loaded successfully. – Luke Vo Mar 17 '23 at 05:39
28

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);
Salomon Arias
  • 281
  • 3
  • 5
  • 2
    Just do this and be happy. Twerking with IIS did not work for me in windows 10 2004. I tried every posible combination. This worked like a charm – Daniel Dolz Aug 22 '20 at 15:22
13

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 found the solution here.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Alejandro PC
  • 191
  • 1
  • 4
  • 1
    I don't have enough words to describe the gratitude I feel towards you for this simple fix! Thank you!! In my case everything worked fine locally, but on azure I was receiving the ".. cannot find the file specified" error. This fixed it – Reath Nov 19 '18 at 12:08
6

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);
m12lrpv
  • 997
  • 2
  • 11
  • 18
  • 1
    Epic catch. Turns out the whole reason I got this error was because my path to my Certificate was slightly off. – Suamere Jan 04 '18 at 02:39
6

You need to specify absolute path instead of relative path.

AppDomain.CurrentDomain.BaseDirectory +"/Certificate/cer.PFX"
2

For those who are trying to access the certificate from the Windows certificate store (Certificates (Local Computer)), be sure to given the application pool user access to the certificate's private key using Action -> All Tasks -> Manage Private Keys... Not doing that turned out to be the cause of me getting this error.

schmiddy98
  • 91
  • 3
  • 6
  • this is what I needed thanks - I used this guide to add my application pool to the permission set since the app pool isn't running as a user - https://community.progress.com/s/article/How-to-set-folder-permissions-for-a-site-that-uses-ApplicationPoolIdentity – Poat Aug 30 '22 at 18:59
0

To add on schmiddy98 answer above I allowed access to IIS user to this folder:

C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
James Risner
  • 5,451
  • 11
  • 25
  • 47