X509Спецификатор Сертификат Исключение - PullRequest
67 голосов
/ 31 марта 2012
//cert is an EF Entity and 
//    cert.CertificatePKCS12 is a byte[] with the certificate.

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

При загрузке сертификата из нашей базы данных на нашем промежуточном сервере (Windows 2008 R2 / IIS7.5) мы получаем следующее исключение:

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)

ПРИМЕЧАНИЕ: Эта проблема не возникает локально (Windows 7 / Casini).

Любое понимание очень ценится.

Ответы [ 7 ]

117 голосов
/ 07 апреля 2012

Оказывается, в конфигурации пула приложений IIS есть настройка (Пулы приложений> Расширенные настройки), чтобы загрузить профиль пользователя для идентификатора пользователя пула приложений. Если установлено значение false, контейнеры ключей недоступны.

Так что просто установите Load User Profile параметр как True

image Advanced Settings Screen">

55 голосов
/ 03 апреля 2012

Скорее всего, когда вы работаете из Visual Studio / Cassini, он обращается к вашему пользовательскому хранилищу сертификатов, даже если вы загружаете его из байтов.Не могли бы вы попробовать это и посмотреть, решит ли это вашу проблему:

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

Это заставит IIS (который работает как пользователь ASP.NET, который, вероятно, не имеет доступа к хранилищу пользователей) использоватьМашинный магазин.

Эта страница объясняет конструктор более подробно, а эта страница объясняет перечисление X509KeyStorageFlags.

Редактировать: Исходя из второй ссылки из cyphr , похоже, что это может быть хорошей идеей (если предыдущее решение не работает) объединить некоторые из FlagsAttribute перечислимые значения примерно так:

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

Кроме того, если у вас есть доступ, вы можете попробовать изменить настройку пула приложений для использования LocalService (а затем перезапустить AppPool).Это может повысить ваши права доступа до соответствующего уровня, если в этом проблема.

Наконец, вы можете использовать File.WriteAllBytes, чтобы записать содержимое CertificatePKCS12 в файл pfx и посмотреть,Вы можете вручную импортировать его, используя консоль сертификатов в MMC (вы можете удалить после успешного импорта; это просто для проверки).Возможно, ваши данные обманывают или неверный пароль.

29 голосов
/ 20 декабря 2012

Используйте этот код:

certificate = new X509Certificate2(System.IO.File.ReadAllBytes(p12File)
                                   , p12FilePassword
                                   , X509KeyStorageFlags.MachineKeySet |
                                     X509KeyStorageFlags.PersistKeySet | 
                                     X509KeyStorageFlags.Exportable);
6 голосов
/ 01 февраля 2017

У меня были проблемы на Windows 2012 Server R2, где мое приложение не могло загрузить сертификаты для PFX на диск.Все работало бы хорошо, если бы мое приложение работало с правами администратора, и исключение гласило, что доступ запрещен, поэтому это должно быть проблема с разрешениями.Я попробовал некоторые из вышеупомянутых советов, но у меня все еще была проблема.Я обнаружил, что указание следующих флагов в качестве третьего параметра конструктора cert помогло мне:

 X509KeyStorageFlags.UserKeySet | 
 X509KeyStorageFlags.PersistKeySet | 
 X509KeyStorageFlags.Exportable
1 голос
/ 05 июня 2014

Альтернативой изменению профиля загрузки пользователя является использование пула приложений Сетевая служба Удостоверение.

См. Также Что именно происходит при установке LoadUserProfile пула IIS

1 голос
/ 06 апреля 2012

Чтобы действительно решить вашу проблему, а не просто догадаться, что это может быть, нужно уметь воспроизвести вашу проблему . Если вы не можете предоставить тестовый файл PFX с такой же проблемой, вы должны изучить проблему самостоятельно. Первый важный вопрос: источник исключения «Произошла внутренняя ошибка» в части с закрытым ключом PKCS12 или в открытой части самого сертификата?

Поэтому я бы рекомендовал вам повторить тот же эксперимент с тем же сертификатом, экспортированным без закрытого ключа (как файл .CER):

var certificate = new X509Certificate(cert.CertificateCER);

или

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

Это может помочь проверить, является ли источником вашей проблемы закрытый ключ или некоторые свойства сертификата.

Если у вас возникнут проблемы с файлом CER, вы можете безопасно опубликовать ссылку на файл, поскольку он имеет только общедоступную информацию. В качестве альтернативы вы можете по крайней мере выполнить

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

или

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

(вы также можете использовать некоторые другие опции) и опубликовать некоторые части вывода (например, свойства закрытого ключа без самого PRIVATEKEYBLOB).

0 голосов
/ 27 сентября 2013

Вам необходимо импортировать сертификат .cer в хранилище ключей вашего локального компьютера. Нет необходимости импортировать ваш сертификат .p12 - вместо этого используйте второй сертификат, выданный вашей учетной записи Apple. Я думаю, что это должна быть действительная пара сертификатов (один в файловой системе, второй в хранилище ключей). Вам, конечно, придется установить все 3 флага в dll.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...