Сайт на сайтах Azure не обрабатывает X509Certificate2
У меня есть сайт на сайтах Azure (без хостинга), и мне нужно обработать сертификаты .pfx с закрытым ключом.
var x509Certificate2 = new X509Certificate2(certificate, password);
Но я столкнулся с следующим исключением:
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)
В статье http://blog.tylerdoerksen.com/2013/08/23/pfx-certificate-files-and-windows-azure-websites/ я обнаружил, что это происходит, потому что по умолчанию система использует локальный каталог пользователя для хранения ключа. Но у сайтов Azure нет локального каталога профиля пользователя. В этой же статье автор предлагает использовать флаг X509KeyStorageFlags.MachineKeySet
.
var x509Certificate2 = new X509Certificate2(certificate, password, X509KeyStorageFlags.MachineKeySet);
Но теперь у меня есть другое исключение:
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)
Может кто-нибудь помочь мне понять, почему это происходит и как это исправить?
Ответы
Ответ 1
Я думаю, вы нашли обходное решение, но если другие борются с этим, я нашел ответ на этот вопрос в другом вопросе SO:
Как можно построить X509Certificate2 из массива байтов PKCS # 12 throw CryptographicException ( "Система не может найти указанный файл." )?
Магия задает флаги хранения X509KeyStorageFlags. Пример:
var myCertificae = new X509Certificate2(
certificateData,
securePasswordString,
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable);
Ответ 2
В Azure Websites теперь есть встроенная поддержка для установки сертификатов в хранилище сертификатов. Вы дали это выстрел?
Подробности здесь: http://azure.microsoft.com/blog/2014/10/27/using-certificates-in-azure-websites-applications/
Ответ 3
Веб-сайты Azure работают в общей среде. Я предполагаю, что конструктор сертификата пытается создать некоторую временную информацию о экземпляре, и у него нет разрешения.
Возможно, вам придется перейти на размещенную службу, чтобы работать в повышенном контексте и выполнять эту работу.
Также, вы подтвердили правильность пароля? Если для этого не требуется пароль, вам, по крайней мере, нужно передать string.Empty для конструктора. Передача в значение NULL также приведет к этому исключению.
Ответ 4
У меня была точно такая же проблема, и я потратил много часов на ее исправление.
В статье, в которой упоминается последний вызов стека, относится к функции LoadCertFromFile, но в вашем (и моем) случае это LoadCertFromBlob.
Итак, я искал LoadCertFromBlob и нашел это:
Почему X509Certificate2 иногда не удается создать из blob?
Решение заключалось в том, чтобы перейти в IIS и изменить идентификатор пула приложений с "ApplicationPoolIdentity" на "LocalService", чтобы сертификат был загружен в нужную локальную папку.
Ответ 5
В Azure Websites/Web App/Mobile App вы должны использовать план обслуживания приложений, который позволяет вам импортировать сертификат SSL, поэтому он не будет бесплатным или общим. Вы можете импортировать не только SSL-сертификат, но и пример сертификата сертификации кода и использовать его в signtool или из PowerShell.
Я использовал этот метод в https://vmplace.eu/
Если вы попытаетесь использовать бесплатный или общий план, вы получите сообщение об ошибке - поэтому в Azure в этих планах есть другая версия .NET framework.
Вы также можете обратиться к этому проекту: https://github.com/onovotny/SignService
mvpbuzz