2011-06-17 73 views
20

Tengo WinForms aplicación que consume una WCF, y transmitirlo como un parámetro a una función de un certificado:X509Certificate - conjunto de claves no existe

mySvcClient.SendDocument(cert.Export(X509ContentType.SerializedCert, "password")); 
... 

En servicio WCF, que recrea el certificado de la matriz de bytes:

public void SendDocument (byte[] binaryCert) 
{ 
    X509Certificate2 cert = new X509Certificate2(binaryCert, "password"); 
... 

Pero cuando se utiliza el certificado para firmar un xml, tengo el error "conjunto de claves no existe":

if (cert.HasPrivateKey) // WORKS!!! 
{ 
    signedXml.SigningKey = cert.PrivateKey; // THROW "keyset does not exist" EXCEPTION 
... 

¡En mi computadora, la aplicación funciona al 100%! ¡Pero en el WebServer, recibí este error!

La pregunta es: incluso X509Certificate2 recreado a partir de una matriz de bytes, ¿necesito algún permiso especial para acceder a la clave privada?

¡Gracias!

+1

El enlace puede ayudarlo ... http://stackoverflow.com/a/39223239/3857542 –

Respuesta

1

Creo que el problema es que debe agregar la clave al almacén de certificados de la máquina.

32

Si está utilizando Windows Server 2008 o Windows 7, necesita el permiso para leer la clave privada.

  1. use la herramienta FindPrivateKey para encontrar la ruta. Por ejemplo:

FindPrivateKey Mi LocalMachine -n ​​"CN = MyCert" -a

que devuelve la ruta: C: \ Datos de programa \ Microsoft \ Crypto \ RSA \ MachineKeys [Nombre de archivo ]

  1. Ir a que las propiedades del archivo y la ruta abierta

  2. Ir a la pestaña de seguridad

  3. Haga clic en "Editar" y luego "Añadir"

  4. En escritura de diálogo abierto: IIS AppPool \ [su nombre de la aplicación de la piscina] y haga clic en OK

Ahora su grupo de aplicaciones tiene permiso para lee esta clave privada.

+1

Otra forma de establecer los permisos del certificado es mediante el complemento de certificados, descrito aquí: http: // stackoverflow. com/a/3176253/844207 – victorvartan

+0

no se puede agregar el grupo de aplicaciones – Lijo

26

me he enfrentado a este problema, mis certificados en las que tener la clave privada, pero que estaba recibiendo este error (" conjunto de claves no existe ')

Causa: Su sitio Web se ejecuta en' Servicios de red "cuenta o tiene menos privilegios.

Solución: identidad del grupo de aplicaciones para el Cambio "sistema local", restablecer IIS y comprobar de nuevo.Si comienza a funcionar, es un problema de permiso/Menos privilegio, puede suplantar y luego usar otras cuentas también.

+1

También parece haber un escenario donde incluso si la identidad de su grupo de aplicaciones es una cuenta con los permisos correctos, aún necesita otorgarle acceso de lectura al grupo IIS_IUSRS la operación para completar si intenta acceder a la clave privada en el Application_Start para la aplicación. – RMD

+0

en mi caso tuve que cambiar la identidad del grupo de aplicaciones a 'Sistema local' y proporcionar acceso a la clave privada a' IIS_IUSRS'. cert debe ser instalado en la tienda de informática local. – Amit

+0

Este es un enfoque mucho más fácil para el entorno de desarrollo y la implementación. – Dhanuka777

4

Vano Maisuradze answer works. Si está buscando la herramienta FindPrivateKey, se incluye en Windows Communication Foundation (WCF) y Windows Workflow Foundation (WF) Ejemplos para .NET Framework 4, que se puede encontrar aquí: http://www.microsoft.com/en-us/download/confirmation.aspx?id=21459

Una vez descargado y extraído, abra el proyecto: WF_WCF_Samples \ WCF \ Setup \ FindPrivateKey \ CS en Visual Studio y compilarlo. Entonces símbolo del sistema abierto y vaya a: WF_WCF_Samples \ WCF \ Setup \ FindPrivateKey \ CS \ bin

luego continuar con Vano Maisuradze respuesta

7

que estaba enfrentando el mismo problema, y ​​yo no sé cómo (la culpa yo), pero funcionó:

var certificate = new X509Certificate2(filePath, password, 
    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); 

certificate.PrivateKey; // before: error "KeySet does not exist"! 

using (certificate.GetRSAPrivateKey()) { } // pure black magic 

certificate.PrivateKey; // after: just works! lol 

Espero que Jon Skeet pueda responder a este misterio.

+2

@Todo el mundo tenga en cuenta que esta solución se aplica a .Net 4.6 o posterior de acuerdo con la página de MSDN que contiene. –

0

Las cuentas de identidad de grupo de aplicaciones no tienen acceso al almacén de certificados de forma predeterminada.

O cambia a la cuenta Network Services según lo señalado por Vaibhav.Inspirada o usted da acceso al certificado.

Para permitir el acceso hacer el siguiente comando:

WinHttpCertCfg.exe -g c LOCAL_MACHINE \ MIS -s "IssuedToName" -a "ACCOUNTNAME"

Notas:

- The tool may need to be installed first. The setup will place the tool at `C:\Program Files (x86)\Windows Resource Kits\Tools\WinHttpCertCfg.exe`. 
- `IssuedName` is the issuer property of the certificate that the application will attempt to access 
- The command must be run from command prompt with elevated privileges 

Referencia: https://support.microsoft.com/en-us/help/901183/how-to-call-a-web-service-by-using-a-client-certificate-for-authentica Paso 2

También debe habilitar la opción Mark this key as exportable al instalar el certificado.

Cuestiones relacionadas