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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

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