This blog article has been migrated from my old blog and updated. You can read the original post here
How I got burned today ...I needed to write a simple SAML 1.1 provider that would generate a SAML token and sign it using a .pfx certificate.
So I wrote this code in my MVC4 Controller ...
var cert = new X509Certificate2(pfxFile, "myPassword"); var privateKey = cert.PrivateKey;
Used the private key to sign the token, ran it locally with no issue. However, once I published the site to Azure Web Apps I get this error.
[CryptographicException: The system cannot find the file specified.] System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) +33 System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) +0 System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags) +218 System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password) +63 System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password) +58 WAWSPfxTest.Controllers.HomeController.Index() +180
I confirmed that the file did in fact exist.
What happened ??Well it turns out that when you load certificates the system will use a local directory to store the key (??)
The default location for the key is the under the local user profile, and with Azure Web Apps, there is no local user profile directory.
Key Storage Flags to the rescueWith some trial and error I found that the MachineKeySet flag worked on my Azure Web App. So with a quick change to the code it was working again.
var cert = new X509Certificate2(pfxFile, "myPassword", X509KeyStorageFlags.MachineKeySet); var privateKey = cert.PrivateKey;
Note: This Azure Blog Article outlines how to upload and use certificates with Azure Web Apps.
I hope this helps someone.