2011-01-21 15 views
8

Copié el código fuente de una aplicación a otra, ambas ejecutándose en la misma máquina. También estoy usando la misma cadena para containerName a continuación en ambas aplicaciones.El objeto ya existe en RSACryptoServiceProvider

¿Qué impide que mi nueva aplicación lea la clave que se guardó en la otra aplicación? Todas las demás cosas son iguales, conectado a la cuenta de usuario, etc.

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

    // Get error "object already exists" below. 
    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); 

Respuesta

7

¿trató de conceder permisos a cada uno, por ejemplo, para los archivos en "Documents and Settings \ All Users \ Datos de programa \ Microsoft \ Crypto \ RSA \ Machine Keys", ya que no se describe:

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

+0

pueden no aplicarse ya que soy ejecutando el mismo código en dos proyectos diferentes, pero con la misma cuenta de usuario. – LamonteCristo

+0

¿Es esa la ubicación de Windows XP? "C: \ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys" es la ubicación de Vista (y arriba), creo. – granadaCoder

5

Otra solución es establecer el acceso a todo el mundo por código:

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); 
+0

Acabo de toparme con este problema. Utilizando la línea de comando 'aspnet_regiis -pa" SampleKeys "NT AUTHORITY \ NETWORK SERVICE" 'no funcionó, pero su solución hizo el trabajo. ¡Muchas gracias! –

+1

En lugar de "todos" tuve que pasar 'nuevo SecurityIdentifier (WellKnownSidType.WorldSid, null)'. Supongo que no funcionó porque el usuario de "todos" está localizado en mi idioma en mi máquina. – Tom

+2

Así como FYI a cualquiera que lo encuentre, para usar 'CryptoKeyAccessRule', tiene que hacer' usando System.Security.AccessControl', y para 'new SecurityIdentifier' y' WellKnownSidType', está 'using System.Security.Principal'. VS 2015 es bueno para sugerir soluciones para los espacios de nombres, pero cualquiera que use una versión anterior a esta, que quizás no conozca bien los espacios de nombres, podría tener dificultades para descubrir qué importar. Cuéntanos tus ensamblajes cuando importes cosas que están fuera del valor predeterminado. – vapcguy

0

Recientemente me encontré con este problema con múltiples sitios IIS desplegados en un solo servidor (Windows 2008 R2). Nuestro entorno tiene cada sitio ejecutándose en diferentes grupos de aplicaciones, pero en algunos casos, a esos grupos se les puede asignar la misma identidad.

Nuestra aplicación crea una clave si no existe, y la coloca en un contenedor con un nombre basado en la identidad actual. El primer sitio implementado siempre funcionó, pero si desplegáramos otro sitio en otro grupo de aplicaciones con la misma identidad, el segundo fallaría.

Resulta que cuando se almacena la clave, Windows da acceso total al usuario "IIS APPPOOL \ AppPoolName", y no la identidad que hemos asignado al grupo.

Por lo tanto, nuestra solución fue dar el contenedor permisos explícitos a la identidad actual (esto es similar a la respuesta de @ WebMixer, la única diferencia está en la 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); 
+0

Obtuve 'No se puede convertir de 'System.Security.Principal.WindowsIdentity' a 'System.Security.Principal.IdentityReference'' cuando intenté insertar esto, tal como está escrito. Tal vez necesite 'nuevo SecurityIdentifier (System.Security.Principal.WindowsIdentity.GetCurrent(). ToString())'? – vapcguy

+0

No estoy seguro. Supongo que algo podría haber cambiado en los últimos años. Retiramos el código de arriba hace algún tiempo. –

+0

Lo intenté, compila, pero obtuvo el error 'System.ArgumentException: Value was invalid', por lo que no me gustó. Aunque no creo que sea la sintaxis, obtuve el mismo mensaje con la sugerencia de Tom sobre la respuesta de Webmixer ('nuevo SecurityIdentifier (WellKnownSidType.WorldSid, null)'). Si utilicé la respuesta de Webmixer directamente, para usar '" everyone "', obtuve 'CryptographicException: Object already exists'. – vapcguy

Cuestiones relacionadas