c# - microsoft - porta azure
El sitio en Azure Websites no procesa X509Certificate2 (5)
Tengo un sitio en Azure Websites (no Hosted Service) y necesito procesar los certificados .pfx con clave privada allí.
var x509Certificate2 = new X509Certificate2(certificate, password);
Pero me enfrenté con la siguiente excepción:
System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
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)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
En el artículo http://blog.tylerdoerksen.com/2013/08/23/pfx-certificate-files-and-windows-azure-websites/ He encontrado que sucede porque, de manera predeterminada, el sistema usa un directorio local de usuario para almacene la llave. Pero los sitios web de Azure no tienen un directorio de perfil de usuario local. En el mismo artículo, el autor propone usar el indicador X509KeyStorageFlags.MachineKeySet
.
var x509Certificate2 = new X509Certificate2(certificate, password, X509KeyStorageFlags.MachineKeySet);
Pero ahora tengo otra excepción:
System.Security.Cryptography.CryptographicException: Access denied.
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)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
¿Alguien puede ayudarme a entender por qué sucede y cómo solucionarlo?
Azure Websites ahora tiene soporte nativo para instalar certificados en el almacén de certificados. ¿Le has dado una oportunidad?
Detalles aquí: http://azure.microsoft.com/blog/2014/10/27/using-certificates-in-azure-websites-applications/
En Azure Websites / Aplicación web / Aplicación móvil: debe usar el Plan de servicio de aplicaciones que le permite importar certificados SSL, por lo que no debe ser gratuito ni compartido. Puede importar no solo certificado SSL, sino también un certificado de firma de código de ejemplo y usarlo en signtool o desde PowerShell.
Usé este método en https://vmplace.eu/
Si intenta utilizar un plan gratuito o compartido, recibirá un error, por lo que en Azure, en estos planes, existe otra versión de .NET Framework.
También puede consultar este proyecto: https://github.com/onovotny/SignService
mvpbuzz
Los sitios web Azure se ejecutan en un entorno compartido. Supongo que el constructor del certificado está intentando crear información temporal sobre la instancia y no tiene permiso para hacerlo.
Es posible que deba actualizar a un servicio alojado para poder ejecutarlo en un contexto elevado y realizar este trabajo.
Además, ¿has validado que la contraseña es correcta? Si no requiere una contraseña, al menos tiene que pasar la cadena. Vacío al constructor. Pasar en un valor NULO también causaría esta excepción.
Supongo que encontraste una solución, pero si otros están luchando con esto, encontré la respuesta a esto en otra pregunta de SO:
La magia es especificar los flags de almacenamiento X509KeyStorageFlags. Ejemplo:
var myCertificae = new X509Certificate2(
certificateData,
securePasswordString,
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable);
Tuve exactamente el mismo problema y tuve que esforzarme muchas horas para solucionarlo. En el artículo que mencionas, la última llamada a la pila corresponde a la función LoadCertFromFile , pero en tu (y mi) caso es LoadCertFromBlob .
Así que busqué LoadCertFromBlob y encontré esto:
¿Por qué X509Certificate2 a veces no puede crear desde un blob?
La solución fue ir en IIS y cambiar la identidad del grupo de aplicaciones de "ApplicationPoolIdentity" a "LocalService", de modo que el certificado se cargue en la carpeta local correcta.