"Ha ocurrido un error interno." al cargar el archivo pfx con X509Certificate2

79

Estoy intentando usar un certificado autofirmado (c #):

X509Certificate2 cert = new X509Certificate2(
    Server.MapPath("~/App_Data/myhost.pfx"), "pass");

en un servidor de alojamiento web compartido y recibí un error:

System.Security.Cryptography.CryptographicException: An internal error occurred.

seguimiento de pila termina con

System.Security.Cryptography.CryptographicException.
    ThrowCryptogaphicException(Int32 hr) +33
System.Security.Cryptography.X509Certificates.X509Utils.
    _LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, 
        Boolean persistKeySet, SafeCertContextHandle& pCertCtx) +0
System.Security.Cryptography.X509Certificates.X509Certificate.
    LoadCertificateFromFile(String fileName, Object password, 
        X509KeyStorageFlags keyStorageFlags) +237
System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(
    String fileName, String password) +131

En mi máquina de desarrollo se carga bien. La razón por la que cargo * .pfx no es un archivo * .cer porque necesito un acceso de clave privada (el archivo cer se carga bien). Hice pfx en mi dev mochine así:

makecert -r -n "CN=myhost.com, [email protected]" -sky exchange -b 01/01/2009
    -pe -sv myhost.pvk myhost.cer
<b>pvk2pfx</b> -pvk myhost.pvk -spc myhost.cer -pfx myhost.pfx -po pass</code>

Estoy usando la versión v5.131.3790.0 de makecert

casperOne
fuente
Quizás este artículo pueda ayudar: codeproject.com/KB/WCF/wcfcertificates.aspx
Emmanuel
Recibí el mensaje de error the system cannot find the file specified. ¡La respuesta de @Randy Levy funcionó para mí!
Jess

Respuestas:

145

Use la tienda de computadoras local para la clave privada:

X509Certificate2 cert = new X509Certificate2("myhost.pfx", "pass",
    X509KeyStorageFlags.MachineKeySet);

MachineKeySetse describe como "las claves privadas se almacenan en la tienda de computadoras local en lugar de en la tienda de usuario actual". El valor predeterminado sin banderas es colocarlo en la tienda del usuario.

Aunque esté leyendo el certificado desde el disco y almacenándolo en un objeto, las claves privadas todavía se almacenan en la base de datos de claves del proveedor de servicios criptográficos de la API criptográfica de Microsoft. En el servidor de alojamiento, el proceso ASP.NET no tiene permiso para acceder al almacén de usuarios.

Otro enfoque (según algunos comentarios a continuación) es modificar la configuración de IIS o la identidad del grupo de aplicaciones, que funcionan. Sin embargo, esto supone que hay acceso a estos elementos de configuración, lo que puede no ser el caso (por ejemplo, en un entorno de alojamiento compartido).

Randy apoya a Monica
fuente
3
sí, ayuda, gracias. ¿podrías explicar por qué? docs no dice nada útil.
2
Salvaste mi día. Curiosamente, funcionó en mi máquina antes de actualizar la solución a .NET 4.0
Marc Climent
1
De hecho, todo lo que tenía que hacer era configurar el parámetro X509KeyStorageFlags.MachineKeySet. Es realmente triste que la excepción lanzada simplemente indique "Se produjo un error interno". No es muy útil.
Nicholi
2
También puede agregar más privilegios sobre la clave privada a la cuenta asignada al grupo de aplicaciones. O cambie la identidad del grupo de aplicaciones a "Servicio local".
guzart
1
Y para una revisión más rápida de la solución / solución alternativa: stackoverflow.com/questions/9951729/…
Ciprian Teiosanu
13

Probé la solución de Randy de cambiarlo a MachineKeySet, pero luego recibí el mensaje de error:

"clave no válida para su uso en el estado especificado"

Entonces, después de buscar un poco en Google, encontré una publicación que sugería cambiarla a:

var certificate = new X509Certificate2(certKeyFilePath, passCode, 
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet |       
X509KeyStorageFlags.PersistKeySet );

y esto resolvió mis problemas.

Todavía no he probado la sugerencia de cambiar la configuración del grupo de aplicaciones en la configuración de IIS. Para hacer esto, vaya a la Configuración avanzada para el grupo de aplicaciones de su sitio y luego configure "cargar perfil de usuario" en verdadero. Cuando esta configuración es falsa, los contenedores de claves aparentemente no son accesibles.

Myke Black
fuente
Recibí el error mencionado anteriormente y su solución me ayudó a resolverlo. gracias.
dotcoder
No me gustan los comentarios que no ayudan (como este) pero déjame decirte que me salvas el día. ¡Gracias!
rasputino