Сертификаты: не удается найти сертификат и закрытый ключ для расшифровки Ошибка при подписи - PullRequest
4 голосов
/ 14 октября 2010

Я работаю в компании со многими серверами и ПК для разработчиков.Серверы - win2003, разработчики ПК - Windows XP.

На сервере Win2003 с именем preiis01 в среде подготовки производства другие сотрудники компании устанавливают клиентский сертификат, используя любого другого пользователя (domainCompany \ adminsystems) для входа на сервер preiis01.

Любой администратор использует пользователя «domainCompany \ adminsystems» для входа на сервер preiis01 (используя Terminal Server, Remote Desktop для Windows XP).

пользователь admin - domainCompany \ adminsystems ", который устанавливает сертификат.

Пользователь с правами администратора устанавливает его следующим образом:

Имя сеанса, например, "domainCompany \ adminsystems". Сертификат - это файл PFX. Установите PFX и используйте Wizard. Ключ закрытый, а не экспорт, введите.пароль и установка.

Существует веб-приложение, идентификатором AppPool которого является: учетная запись NETWORK SERVICE.

веб-сервером является IIS 6.0.

в preiis01,

Этот пользователь-администратор выполняет mmc -> Snap - -> Сертификаты для локального компьютера. В узле -> Personal -> Certifi.Кейтс, он видел сертификат клиента:

Выдан ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1

Выдан FNMT Clase 2 CA

В свойствах сертификата, отпечаток: "93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13"

Этот пользователь с правами администратора выполняет следующие команды:

winhttpcertcfg.exe LOCAL_MACHINE \My -s "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" -g -a "NETWORK SERVICE"

Результат:

Сертификат соответствия:

CN = ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1

OU = 703015476

OU = FNMT Clase 2 CA

O = FNMT

C = ES

Предоставление доступа к закрытому ключу для учетной записи: NT AUTHORITY \ NETWORK SERVICE

Теперь пользователь с правами администратора выполняет эту команду:

winhttpcertcfg.exe -l -c LOCAL_MACHINE \ My -s "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1"

Результат:

Сертификат соответствия:

CN = ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1

OU = 700012476

OU = FNMT Clase 2 CA

O = FNMT

C = ES

Дополнительные учетные записи и группы с доступом к секретному ключу включают: domainCompany \ adminsystems NT AUTHORITY \ SYSTEM BUILTIN \ Администраторы NT AUTHORITY \ NETWORK SERVICE

NOw, на странице aspx в веб-приложении на сервере Win2003, IIS 6.0, у меня есть этот код:

NOte: значение для X509Certificate2.HasPrivateKeyAccess () равно NO (false) для "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1 "сертификат.

Приложение ASP.NET выполняется с использованием удостоверения :: NT AUTHORITY \ NETWORK SERVICE

lbInfo.Text += "<br/><br/>ASP.NET application executes using the identity :: <b>" + WindowsIdentity.GetCurrent().Name + "</b><br>";


            var store = new X509Store(StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            Certificates = store.Certificates;
            repeater1.DataSource = Certificates;
            repeater1.DataBind();

            var nombreCertificado = "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1";

            store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);

            X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySubjectName, nombreCertificado, false);

            if (col.Count > 0)
            {
                X509Certificate2 certificate = col[0];
                store.Close();
                Message.Text = "Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;

                FirmarConCertificado(nombreCertificado, certificate);

            }
            else
            {
                store.Close();
                Message.Text = "El certificado " + nombreCertificado + " no esta instalado en la máquina";
            }


public void FirmarConCertificado(string nombreCertificado, X509Certificate2 certificate)
{
    try
    {
 var mensaje = "Datos de prueba";
                System.Text.Encoding enc = System.Text.Encoding.Default;
                byte[] data = enc.GetBytes(mensaje);

                var contentInfo = new System.Security.Cryptography.Pkcs.ContentInfo(data);
                var signedCms = new System.Security.Cryptography.Pkcs.SignedCms(contentInfo, true);

                var cmsSigner = new System.Security.Cryptography.Pkcs.CmsSigner(certificate);

                //  Sign the CMS/PKCS #7 message
                signedCms.ComputeSignature(cmsSigner);

                //  Encode the CMS/PKCS #7 message
               var ret = Convert.ToBase64String(signedCms.Encode());

 Message.Text += "Firmado con Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;
 }
 catch (Exception ex)
 {
 Message.Text = "Error al firmar con certificado: " + ex.ToString();
 Message.Text += "<br /><br />InnerException: " + ex.InnerException;
 }

}

Код не выполняется для меня,и я получаю эту ошибку: Не удается найти сертификат и закрытый ключ для расшифровки.

Строка ошибки: signatureCms.ComputeSignature (cmsSigner);

Ошибка al firmar con Certificado: System.Security.Cryptography.CryptographicException: Невозможно найти сертификат и закрытый ключ для расшифровки.

в System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo (подписчик CmsSigner, логическое молчание) в System.Security.Cryptography.k.Подпишите (подписчик CmsSigner, логическое молчание) в System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature (подписчик CmsSigner, логическое молчание) в System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature (CmsSigner_Fortest_Fer_Signer_FerSigner_FerSigner_FerSigner_FerSigner_FerSignerF_Signer_FerSigner)Строка nombreCertificado, сертификат X509Certificate2) в c: \ Company \ App \ Test \ TestCert.aspx: строка 242

Затем пользователь с правами администратора (я помню, кто устанавливал сертификат) выполняет следующие команды:

FindPrivateKey My LocalMachine -t "93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13 "–c

FindPrivateKey My LocalMachine -n ​​"ENTIDAD COMPANY INSURE SA - CIF A93 - ИМЯ ФАМИЛИЯ1 ИМЯ1" - a

FindPrivateKey My LocalMachine -n "CN = ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" -a

Результат для всех 3 команд одинаков:

FindPrivateKey помогает пользователю найти расположение файла закрытого ключа X.50 9 сертификат.

Использование: FindPrivateKey [{{-n} | {-t} } [-f | -d | -a]]

тема имени сертификат

отпечаток большого пальца сертификат (используйте certmgr.exe для получения она)

-f только имя выходного файла

-d только каталог вывода

-a выходной абсолютный файл имя например FindPrivateKey My CurrentUser -n "CN = John Doe"

например. FindPrivateKey My LocalMachine -t "03 33 98 63 d0 47 e7 48 71 33 62 64 76 5 c 4c 9d 42 1d 6b 52 "-c

FindPrivateKey ничего не получает, но winhttpcertcfg.exe -l работает нормально (соответствующий сертификат)

Мы дали привилегии пользователю сетевой службы с помощью инструмента winhttpcertcfg.exe, и в коде ASP.NET (выполняется под учетной записью сетевой службы) сертификат найден. Но не удается, когда подписать с помощью сертификата.

Если кто-то может дать нам некоторую информацию или предложения

Обновление:

Пользователь в домене "domainCompany \ Pre_Certificado" устанавливает сертификат в хранилище локального компьютера.

domainCompany \ Pre_Certificado - Администратор, в группе IIS_WPG имеет локальные политики: «Войти в систему как служба» *

Я настраиваю AppPool Identity в IIS 6.0 для: domainCompany \ Pre_Certificado

Приложение ASP.NET выполняется с использованием удостоверения :: domainCompany \ Pre_Certificado

Я перезапускаю AppPool и запускаю приложение, я получаю System.Security.Cryptography.CryptographicException: не удается найти сертификат и закрытый ключ для расшифровки

Если я протестирую снова, войдите в сеанс на сервере IIS, используя пользователя domainCompany \ Pre_Certificado, я вызываю страницу в приложении ASP.NET, и все в порядке.

(примечание: войти на сервер IIS с использованием Terminal Server)

Но если выйти из сеанса на сервере IIS (пользователь: domainCompany \ Pre_Certificado), я получаю ту же ошибку:

System.Security.Cryptography.CryptographicException: не удается найти сертификат и закрытый ключ для расшифровки

Есть предложения ??

Ответы [ 3 ]

4 голосов
/ 17 ноября 2010

Выполните первые 2 шага так же, как и при IIS 7.5 (нажмите здесь)

  1. Создание / покупка сертификата.Убедитесь, что у него есть закрытый ключ.
  2. Импортируйте сертификат в учетную запись «Локальный компьютер».Лучше всего использовать сертификаты ММС. Обязательно установите флажок «Разрешить экспорт закрытого ключа»
  3. Запустите приведенную ниже команду от имени администратора.Замените следующее:

    • Замените [Subject] на предмет сертификата и используйте кавычки, если он содержит пробелы.Я думаю, что вы также можете просто поставить первое слово, если нет другого сертификата, который начинается с той же темы.
    • Замените [Store] хранилищем сертификатов, в которое вы импортировали, по умолчанию я считаю «ROOT» или «MY» на IIS 6, т.е. «LOCAL_MACHINE \ ROOT» или «LOCAL_MACHINE \ MY»
    • Замените [имя_компьютера] на имя компьютера.Возможно, вы сможете использовать нотацию ". \" Для [computernam], т.е. ". \ NETWORK SERVICE", но я не пробовал.

winhttpcertcfg.exe -g -a "[имя_компьютера] \ NETWORK SERVICE" -c LOCAL_MACHINE \ [Store] -s "[Тема]"

Примечание: Если вы используете пул приложений ASP.NET под другим именемкроме «NETWORK SERVICE» вам потребуется изменить «NETWORK SERVICE» в вышеприведенной команде на удостоверение того, что вы используете пул приложений IIS.

2 голосов
/ 17 ноября 2010

Пожалуйста, отметьте этот документ , который поможет вам решить проблему. Я бы порекомендовал использовать следующую команду:

winhttpcertcfg -g -c LOCAL_MACHINE\My -s MyCertificate -a TESTUSER 
0 голосов
/ 14 октября 2010

Может также потребоваться предоставить доступ анонимному пользователю.Если вы разрешаете анонимный доступ, то запрос выполняется как анонимный пользователь, а не как сетевой сервис.

...