Jump to content
miegir

Проблема С Поиском Контейнера Закрытого Ключа Для Сертификата, Загруженного Из Файла

Recommended Posts

В одном из наших проектов требуется выполнить подпись сообщения при помощи сертификата. Имеем следующее:

  1. Установленный VipNet CSP. Проблема воспроизводится на разных версиях, на данный момент установлена версия 3.2 (11.16035).
  2. Контейнер VipNet с сертификатом и закрытым ключом на жестком диске.
  3. Имя файла и путь к файлу контейнера изменены после создания контейнера, изначальный контейнер отсутствует в VipNet CSP.
  4. Контейнер добавлен в приложении VipNet CSP, сертификат установлен в хранилище сертификатов пользователя и компьютера (чтобы наверняка) с привязкой к контейнеру, в оснастке сертификатов сертификат виден и отображается со значком закрытого ключа.
  5. Сертификат экспортирован в файл .cer в DER-кодировке (без закрытого ключа).

Алгоритм для воспроизведения проблемы в программном коде:

  1. Загружаем сертификат из файла .cer.
  2. Получаем закрытый ключ данного сертификата.

Проблема состоит в том, что при получении закрытого ключа VipNet CSP пытается найти контейнер по изначально созданному пути. Т.к. этого контейнера больше нет, выводится диалоговое окно для указания пути к контейнеру. Этой проблемы хотелось бы избежать, не указывая правильный путь к контейнеру явно. Т.е. требуется понять, почему VipNet CSP ищет контейнер по оригинальному пути и как исправить этот путь на правильный (т.е. на текущий путь к контейнеру).

Пример кода, воспроизводящего проблему, на C# с использованием CADESCOM (от КриптоПро):


var signer = new CPSigner();
var signedData = new CadesSignedData();
var cer = new Certificate();

cer.Load(@"C:\temp\tmp.cer"); // путь к экспортированному сертификату
signer.Certificate = cer;
signedData.Content = data;

// в следующей строке отображается диалог для поиска контейнера с закрытым ключом
var signature = signedData.SignCades(signer, CADESCOM_CADES_TYPE.CADESCOM_CADES_BES, true);

signedData.Display();

Пример кода, воспроизводящего проблему, на C++ с использованием только WinApi:


// в pbData находится содержимое сертификата, считанное из файла C:\temp\tmp.cer
PCCERT_CONTEXT pContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pbData, cbData);

// в следующей строке отображается диалог для поиска контейнера с закрытым ключом
CryptAcquireCertificatePrivateKey(pContext, CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &ph, &pdw, &pf);

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

Пример кода, работающего нормально, на C# с использованием CADESCOM (от КриптоПро):


var signer = new CPSigner();
var signedData = new CadesSignedData();

signedData.Content = data;

// в следующей строке отображается лишь диалог для ввода пароля к контейнеру, если пароль еще не сохранен
var signature = signedData.SignCades(signer, CADESCOM_CADES_TYPE.CADESCOM_CADES_BES, true);

signedData.Display();

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.