We have a website deployed on two web apps on Azure : a production and a pre-production version.
The website at certain time creates a container to host RSA keys, using the below code :
// -----------------------------
// Part 1 : Initialize csp params
// -----------------------------
const int PROVIDER_RSA_FULL = 1;
const string CONTAINER_NAME = "OurKeyContainer";
CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";
// --------------------------------------------------
// Part 2 : A try to set folder access rights to "everyone"
// --------------------------------------------------
// http://whowish-programming.blogspot.fr/2010/10/systemsecuritycryptographycryptographic.html
// http://stackoverflow.com/questions/5013881/c-sharp-how-do-i-get-the-everybody-user
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var rule = new CryptoKeyAccessRule(sid, CryptoKeyRights.FullControl, AccessControlType.Allow);
cspParams.CryptoKeySecurity = new CryptoKeySecurity();
cspParams.CryptoKeySecurity.SetAccessRule(rule);
return new RSACryptoServiceProvider(cspParams);
The issue is that this code works only for one of the website, the one that was first launched actually. The second one threw a CryptographicException "Object already exists".
After googling , the issue seems to be caused by users executing the website that do not have right to access the key container, but unfortunately the recommended fix (implemented in Part 2 on our code above) does not work ..
Any idea or advice ?
Thanks
Riana
I think the problem is that you are basically trying to create a Machine wide container with the same name two times. I am assuming that the
pre-prod
andprod
environments are on the same machine, perhaps as deployment slots in your App Service? I could replicate your problem with this setup at least. There are some other setups that could produce the same situation I guess, but this is the most likely.There are three things you can change in this setup that will produce different results:
For identity we can use either
Everyone
(as you have tried) orCurrent
which we can get from WindowsIdentityThe container store can be either
machine wide
or just for the current userAnd for the store name we can choose something, in your case you choose the same but we can set something that is unique for the identity as well
The different combinations will produce different results:
Everyone identity, machine wide store, same container name Fails on one of the slots with
System.Security.Cryptography.CryptographicException: Object already exists.
Everyone identity, machine wide store, container per identity OK
Everyone identity, user store, same container name Fails on both of the slots with
System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
Everyone identity, user store, container per identity OK
Current identity, machine wide store, same container name Fails on one of the slots with
System.Security.Cryptography.CryptographicException: Object already exists.
Current identity, machine wide store, container per identity OK
Current identity, user store, same container name Fails on both of the slots with
System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
Current identity, user store, container per identity Fails on both of the slots with
System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
So, to summarize, changing the name of the container to include something that is unique for the environment will fix the problem. It doesn't have to be the identity (but you will get one identity per App Service you are running on a machine so it is fairly safe), it could be the name of the environment if you set it as an
ENVIRONMENT VARIABLE
in your App Service and make sure it is set topre-prod
andprod
respectively.Here is the playaround code to test it