I have my X509Certificate stored in a database (in byte[]
) so that my application can retrieve the certificate and use it to sign my JWTs.
My x509Certificate is passed off a .pfx file that I generated on my machine, however now it sits in a database as a string of bytes.
My application works perfectly fine locally when I run it. The application can correctly create an instance of that X509Certificate2 and use it for my requirements, however the problem arises when I try to use it in my azurewebsites web application.
Basically I can not access the certificates' PrivateKey instance variable, I get an exception
System.Security.Cryptography.CryptographicException: Keyset does not exist
And I am re-instantiating the certificate with this
var cert = new X509Certificate2(myCertInBytes, myCertPass,
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.Exportable);
I am using ASPNET 5 rc1-update1. I have also tried running this on a different machine and it works fine, only have this issue when I publish to Azure. And to also add something else, This application was working when I was running the same project that was running using DNX version beta7
Any help appreciated.
The problem is the Azure Web Apps restricts access to the machines private key store, since it's a shared hosting environment, and you don't fully own the machine. As a workaround, you can load a cert. This blog post describes the best practice on how to do so: https://azure.microsoft.com/en-us/blog/using-certificates-in-azure-websites-applications/
Please note that this only works for Basic Tier and above (not Free or Shared tier).
This can also be done from a .cer file as follows, however it should be noted that this is not best-practices since you're storing a secure credential with your code, in an insecure format.
public X509Certificate2 CertificateFromStrings(String certificateString64, String privateKeyXml)
{
try
{
var rsaCryptoServiceProvider = new RSACryptoServiceProvider();
rsaCryptoServiceProvider.FromXmlString(privateKeyXml);
var certificateBytes = Convert.FromBase64String(certificateString64);
var x509Certificate2 = new X509Certificate2(certificateBytes);
x509Certificate2.PrivateKey = rsaCryptoServiceProvider;
return x509Certificate2;
}
catch
{
return null;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With