@PitSullivan

Как импортировать криптографические ключи в контекст криптопровайдера?

Перейдём сразу к сути вопроса.
Дан PFX-файл. Необходимо извлечь из него ключевую пару и записать её на eToken. Казалось бы, ничего сложного. Подключай CryptoAPI, иди на MSDN и разбирайся. Однако обилие различных функций, которые предлагает этот интерфейс для реализации различных криптографических операций, наверняка вскружит голову даже бывалому разработчику (коим я, к слову, пока не являюсь). В SDK, с которым я работаю, есть пример того, как это можно было бы сделать. Однако, моя реализация, мягко говоря, почему-то не работает должным образом. Если на чистоту, то она вообще не работает. Программа завершает свою работу с ошибкой NTE_NO_KEY. Ошибку генерирует функция CryptGetUserKey.
Не имя опыта работы с CAPI, а также представлений о том, каким образом извлечь ключи, я стал изучать готовый пример, чтобы понять ход мыслей писавшего его программиста. Вот что мне удалось извлечь из этого кода:
1. Сперва необходимо верифицировать PFX-контейнер (PFXIsPFXBlob и PFXVerifyPassword нам в этом помогут).
2. Затем нужно импортировать содержимое контейнера во временное хранилище (назовём его CertStore).
3. После этого нужно найти в этом хранилище сертификат открытого ключа и получить информацию о требуемом криптопровайдере (что можно осуществить с помощью функций CertEnumCertificateInStore и CertGetCertificateContextProperty со значением CERT_KEY_PROV_INFO_PROP_ID аргумента dwPropId).
4. Далее нужно получить дескриптор требуемого CSP (CryptAquireContext в помощь).
5. Наконец, нужно получить дескриптор контейнера с ключами в контексте криптопровайдера и извлечь их (CryptGetUserKey и CryptExportKey помогут нам в этом).
6. После этого мы можем делать с ними всё, что пожелаем (в рамках дозволенного).
Так вот, программа "валится" на пятом шаге с ошибкой "They key requested by the dwKeySpec parameter does not exist" ("Запрашиваемый ключ с характеристиками, специфицированными параметром dwKeySpec, не существует") . Значение параметра dwKeySpec может быть либо AT_KEYEXCHANGE, либо AT_SIGNATURE. В качестве аргумента передаётся первое значение.
Почитав описание функций CryptAquireContext и CryptGetUserKey, я пришёл к выводу, что они лишь предоставляют дескрипторы соответствующих контекстов (криптопрвайдера и контейнера с ключами внутри него). Однако я нигде явно не инициализировал контекст контейнера с ключами. Так откуда же им там взяться? Это могло бы объяснить возникшую ошибку. Тогда возникает вопрос: если в этой последовательности действий нет пропущенных шагов, то как же тогда ключи попадают в контейнер CSP, и с чем связана ошибка?
Если же чего-то не хватает, то чего именно?
Прошу прощения за размер содержания. Я старался как можно подробнее описать проблему.
ВАЖНОЕ ОБНОВЛЕНИЕ: прошу прощения за то, что ввёл вас в заблуждение, программа из примера всё же работает корректно! Не работает моя версия, которая отличается от исходной лишь тем, что необходимые мне библиотеки подключаются динамически. Отсюда можно сделать вывод, что пропущенных шагов здесь нет. Однако вопрос о том, как же ключи попадают в контейнер, остаётся открытым.
  • Вопрос задан
  • 3780 просмотров
Пригласить эксперта
Ответы на вопрос 1
Вы разбирали пример из их SDK
samples\CAPI\ImportPFX\ImportPFX.cpp
?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы