X509Certificate Constructor Exception

//cert is an EF Entity and // cert.CertificatePKCS12 is a byte[] with the certificate. var certificate = new X509Certificate(cert.CertificatePKCS12, "SomePassword"); 

Al cargar un certificado de nuestra base de datos, en nuestro servidor de ensayo (Windows 2008 R2 / IIS7.5) obtenemos esta excepción:

 System.Security.Cryptography.CryptographicException: An internal error occurred. at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags) 

NOTA: Este problema no ocurre localmente (Windows 7 / Casini).

Cualquier idea es muy apreciada.

Resulta que hay una configuración en la configuración del grupo de aplicaciones IIS (Grupos de aplicaciones> Configuración avanzada) para cargar el perfil de usuario para el usuario de identidad del grupo de aplicaciones. Cuando se establece en falso, los contenedores de claves no son accesibles.

Así que simplemente configure la opción Load User Profile como True

Pool de aplicaciones-/> Pantalla de configuración avanzada”> </p>
</div>
</li><!-- #comment-## -->
<div class=

Lo más probable es que cuando esté ejecutando Visual Studio / Cassini, esté accediendo a su almacén de certificados de usuario , aunque lo esté cargando desde bytes. ¿Podría probar esto y ver si resuelve su problema?

 var certificate = new X509Certificate( cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet); 

Esto hará que IIS (que se ejecuta como el usuario de ASP.NET que probablemente no tiene acceso a una tienda de usuario) use el almacén de máquinas.

Esta página explica el constructor con más detalle, y esta página explica la enumeración X509KeyStorageFlags .

Editar: basado en el segundo enlace de cyphr , parece que podría ser una buena idea (si la solución anterior no funciona), combinar algunos de los valores de enumeración de FlagsAttribute de la FlagsAttribute manera:

 var certificate = new X509Certificate( cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); 

Además, si tiene acceso, puede intentar cambiar la configuración del grupo de aplicaciones para usar LocalService (y luego reiniciar el AppPool). Esto puede elevar sus permisos a un nivel apropiado si ese es el problema.

Finalmente, puede usar File.WriteAllBytes para escribir el contenido de CertificatePKCS12 en un archivo pfx y ver si puede importarlo manualmente utilizando la consola de certificados en MMC (puede eliminarlo después de la importación exitosa; esto es solo para probar). Podría ser que sus datos estén siendo contaminados o que la contraseña sea incorrecta.

Usa este código:

 certificate = new X509Certificate2(System.IO.File.ReadAllBytes(p12File) , p12FilePassword , X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); 

Tuve un problema en Windows 2012 Server R2 donde mi aplicación no pudo cargar certificados para un PFX en el disco. Las cosas funcionarían bien al ejecutar mi aplicación como administrador, y la excepción decía Acceso denegado, por lo que tenía que ser un problema de permisos. Intenté algunos de los consejos anteriores, pero aún así tuve el problema. Encontré que especificar los siguientes indicadores como el tercer parámetro del constructor de cert me funcionó:

  X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable 

Para poder realmente resolver su problema y no solo adivinar, cuál puede ser, uno debe ser capaz de reproducir su problema . Si no puede proporcionar el archivo PFX de prueba que tiene el mismo problema, debe examinar el problema usted mismo. La primera pregunta importante es: ¿el origen de la excepción fue “Se produjo un error interno” en la parte de clave privada de PKCS12 o en la parte pública del certificado en sí?

Así que le recomendaría que intente repetir el mismo experimento con el mismo certificado, exportado sin clave privada (como el archivo .CER):

 var certificate = new X509Certificate(cert.CertificateCER); 

o

 var certificate = new X509Certificate.CreateFromCertFile("My.cer"); 

Podría ayudar a verificar si el origen de su problema es la clave privada o algunas propiedades del certificado.

Si tiene un problema con el archivo CER, puede publicar el enlace al archivo porque solo tiene información pública. Alternativamente, al menos puede ejecutar

 CertUtil.exe -dump -v "My.cer" 

o

 CertUtil.exe -dump -v -privatekey -p SomePassword "My.pfx" 

(también puede usar algunas otras opciones) y publicar algunas partes de la salida (por ejemplo, propiedades de la clave privada sin PRIVATEKEYBLOB).

Una alternativa para cambiar el perfil de usuario de carga es hacer que el grupo de aplicaciones use la identidad del servicio de red .

Consulte también ¿Qué sucede exactamente cuando configuro LoadUserProfile del conjunto de IIS?

Debe importar un certificado .cer a su almacén de claves de la máquina local. No es necesario importar su certificado .p12; en su lugar, utilice el segundo certificado emitido en su cuenta por Apple. Creo que debe ser un par válido de certificados (uno en el sistema de archivos, el segundo en el almacén de claves). Tendrás que establecer las 3 banderas en dll, por supuesto.