"Возникла внутренняя ошибка." При загрузке файла PFX с помощью x509Certificate2

StackOverflow https://stackoverflow.com/questions/1345262

  •  20-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь использовать самозаверяющий сертификат (С#):

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

на общем сервере веб-хостинга, и я получил ошибку:

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

трассировка стека заканчивается на

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

На моей машине разработчика все загружается нормально.Причина, по которой я загружаю *.pfx, а не файл *.cer, заключается в том, что мне нужен доступ к секретному ключу (файл cer загружается нормально).Я сделал pfx на своей машине разработчика следующим образом:

makecert -r -n "CN=myhost.com, E=admin@myhost.com" -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>

Я использую версию makecert v5.131.3790.0.

Это было полезно?

Решение

Используйте локальный компьютерный магазин для получения закрытого ключа:

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

MachineKeySet описывается как «закрытые ключи хранятся в хранилище локального компьютера, а не в хранилище текущего пользователя».По умолчанию без флагов помещается в хранилище пользователя.

Даже если вы читаете сертификат с диска и сохраняете его в объекте, закрытые ключи по-прежнему хранятся в базе данных ключей поставщика службы шифрования Microsoft Cryptographic API.На хост-сервере процесс ASP.NET не имеет разрешения на доступ к хранилищу пользователей.

Другой подход (согласно некоторым комментариям ниже) заключается в изменении идентификации конфигурации IIS или пула приложений, что действительно работает.Однако это предполагает наличие доступа к этим элементам конфигурации, что может быть не так (например,в среде общего хостинга).

Другие советы

Я попробовал решение Рэнди, изменив его на MachineKeySet, но затем получил сообщение об ошибке:

«ключ недействителен для использования в указанном состоянии»

Итак, немного погуглив, я нашел сообщение, в котором предлагалось изменить его на:

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

и это решило мои проблемы.

Я еще не попробовал предложение изменить настройку пула приложений в конфигурации IIS.Для этого перейдите в дополнительные настройки пула приложений вашего сайта и установите для параметра «Загрузить профиль пользователя» значение true.Если этот параметр имеет значение false, контейнеры ключей, очевидно, недоступны.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top