Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object already exists in RSACryptoServiceProvider

I copied the source code from one application to another, both running on the same machine. I am also using the same string for containerName below in both applications.

What is preventing my new application from reading the key that was saved in the other application? All other things are equal, logged in user account etc.

     CspParameters cspParams = new CspParameters();
     cspParams.KeyContainerName = containerName;
     cspParams.Flags = CspProviderFlags.UseMachineKeyStore;

     // Get error "object already exists" below.
     RSACryptoServiceProvider  rsaKey = new RSACryptoServiceProvider(cspParams);
like image 990
makerofthings7 Avatar asked Jan 21 '11 20:01

makerofthings7


3 Answers

I recently ran into this issue with multiple deployed IIS sites on a single server (Windows 2008 R2). Our environment has each site running on different application pools, but in some cases, those pools can be assigned the same identity.

Our application creates a key if one does not exist, and places it in a container with a name based on the current identity. The first deployed site always worked, but if we deployed another site into another app pool with the same identity, the second would fail.

Turns out that when the key is stored, Windows gives full access to the user "IIS APPPOOL\AppPoolName", and not the identity that we have assigned to the pool.

So, our solution was to give the container explicit permissions to the current identity (this is similar to @Webmixer's answer, the only difference is in the CryptoKeyAccessRule):

CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";

CryptoKeyAccessRule rule = new CryptoKeyAccessRule(System.Security.Principal.WindowsIdentity.GetCurrent(), CryptoKeyRights.FullControl, AccessControlType.Allow);

cspParams.CryptoKeySecurity = new CryptoKeySecurity();
cspParams.CryptoKeySecurity.SetAccessRule(rule);
like image 126
Steve Czetty Avatar answered Sep 28 '22 08:09

Steve Czetty


Another solution is to set access to everyone by code :

CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";

CryptoKeyAccessRule rule = new CryptoKeyAccessRule("everyone", CryptoKeyRights.FullControl, AccessControlType.Allow);

cspParams.CryptoKeySecurity = new CryptoKeySecurity();
cspParams.CryptoKeySecurity.SetAccessRule(rule);
like image 29
FredPonch Avatar answered Sep 28 '22 08:09

FredPonch


Did you try to grant permissions to Everyone, for example, for files in "Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Machine Keys", as it described there:

http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/f7b9f928-a794-47f2-a5bd-9f64ca375040

like image 41
Pavel Morshenyuk Avatar answered Sep 28 '22 07:09

Pavel Morshenyuk