When loading X.509 certificates using the .NET X509Certificate2 class, always specify the X509KeyStorageFlags.MachineKeySet flag. This ensures the certificate may be accessed from within IIS. For example:
X509Certificate2 x509Certificate = new X509Certificate2(“idp.pfx”, “password”,
X509KeyStorageFlags.MachineKeySet);
Certificates Stored in Files
When loading a certificate from file, if an access denied exception occurs, this generally indicates a file permissions error.
Firstly, make sure the process the application is running under has permission to read the certificate file. For example, ensure the IIS_USERS group has read permission to the idp.pfx file.
If the permissions are correct for the pfx file, then the issue lies with the private key.
Private keys are stored in containers on the file system. The location of the private key container on Windows 7/8/10 and Windows Server 2008/2012/2016 is:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
The FindPrivateKey.exe Windows SDK utility may be run to locate the private key container.
http://msdn.microsoft.com/en-us/library/aa717039.aspx
The application process must have permission to create a file in the private key container folder.
The following code dumps out a certificate:
X509Certificate2 x509Certificate = new X509Certificate2(“idp.pfx”, “password”,
X509KeyStorageFlags.MachineKeySet);
Trace.Write(x509Certificate.ToString(true));
Its output is:
[Version]
V1
[Subject]
CN=www.idp.com
Simple Name: www.idp.com
DNS Name: www.idp.com
[Issuer]
CN=www.idp.com
Simple Name: www.idp.com
DNS Name: www.idp.com
[Serial Number]
46D399D0
[Not Before]
8/28/2007 1:43:12 PM
[Not After]
8/25/2017 1:43:12 PM
[Thumbprint]
4E387A0C0B695DB05F5DFD70D2572BB0FEBB98BA
[Signature Algorithm]
md5RSA(1.2.840.113549.1.1.4)
[Public Key]
Algorithm: RSA
Length: 1024
Key Blob: 30 81 89 02 81 81 00 a3 7d 6a de 62 59 6b 25 df 66 42 c3 b8 b7 27 6a 77 3f 28 6f 91 0c 55 be 3a 56 03 3f e4 6e 6e f5 a7 b7 c5 f9 8e d8 94 4d ca 7c 21 0e 3a 4c d1 14 16 c9 26 b2 89 d4 6f 90 27 1b ec ce 09 c6 b0 6f 67 49 af c9 01 b4 23 61 7e 2f d3 b9 f6 46 05 03 63 b8 0c 4d 32 2d f8 c8 88 11 74 68 a7 6b 39 c7 81 c9 6b 00 82 19 4f 22 9e ad 0a 98 8c f2 f5 c5 10 ec 14 6a 73 a8 61 a2 ff 6a 29 cc df 27 57 99 02 03 01 00 01
Parameters: 05 00
[Private Key]
Key Store: Machine
Provider Name: Microsoft Base Cryptographic Provider v1.0
Provider type: 1
Key Spec: Exchange
Key Container Name: {7D7021F3-C4E9-44C2-BB68-ECD0517EF5FE}
Unique Key Container Name: 1cff1ca21ad134bb7e6e87ee27ff71d3_cddd8d16-473b-40eb-8c9f-9cb4b8d44d33
Hardware Device: False
Removable: False
Protected: False
Note the unique key container name. This name is different each time the certificate is loaded.
At the time the certificate is loaded, a file with the private key container name is created in the private key container (e.g. C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\7D7021F3-C4E9-44C2-BB68-ECD0517EF5FE).
The application process must have permission to create files in this container.
Certificates Stored in the Windows Certificate Store
When loading a certificate from the Windows Certificate Store, if an access denied exception occurs, this generally indicates a permissions error.
Firstly, make sure the certificate is stored in the local computer store rather than the current user’s store. This ensures the certificate may be accessed from within IIS.
Select the certificate, and click the menu Action > All Tasks > Manage Private Keys.
Make sure the application process (e.g the IIS_IUSRS group) has read access.