I faced the following issue.
I run the following code
var binaryData = File.ReadAllBytes(pathToPfxFile);
var cert = new X509Certificate2(binaryData, password);
in two processes. One of the processes runs under LOCAL_SYSTEM
and there this code succeeds. Another one runs inside IIS under a local user account belonging to "Users" local group and there I get the following exception:
System.Security.Cryptography.CryptographicException
Object was not found.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password)
//my code here
So I Googled a bit and found this answer to a kind of similar question. I tried to enable LoadUserProfile
for the application pool and it works now.
The problem is I don't get what exactly happens when I set LoadUserProfile
and what consequences that might have. I mean if it's a "good" thing then why it is not "on" by default and why is it there after all?
What exactly happens when I set LoadUserProfile
in IIS pool and what negative consequences can it have?
I mean if it's a "good" thing then why it is not "on" by default and why is it there after all?
IIS 6 never loaded user profiles. I would assume this is off by default to keep the behavior consistent, and an administrator has to opt-in to it.
I tried to enable LoadUserProfile for the application pool and it works now.
This is most likely because the Windows Cryptographic Service Provider was trying to store or load a key for your certificate in the user store, and since a profile was not available, a cryptographic context was not available. Note that the Load User Profile
setting only applies to user accounts. Service Accounts like NETWORK SERVICE and ApplicationPoolIdentity have special handling.
What exactly happens when I set LoadUserProfile in IIS pool
Well, the user profile is loaded. This includes their cryptographic store, environment variables such as %TEMP%, and other ones.
What it eventually boils down to is LoadUserProfile
is called by IIS when the AppPool starts.
what negative consequences can it have?
It may break backwards compatibility with an app that ran on IIS 6, which didn't load the user profile. The environment variables are loaded. For example, when Load User Profile is true, the %TEMP% environment variable is C:\Users\AccountName\AppData\Local\Temp
(for example). When false, it's C:\WINDOWS\Temp
.