Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline devyatyarov.andrey  
#1 Оставлено : 20 мая 2014 г. 11:51:43(UTC)
devyatyarov.andrey

Статус: Участник

Группы: Участники
Зарегистрирован: 08.05.2014(UTC)
Сообщений: 12
Мужчина
Российская Федерация

Помогите решить задачу.
Есть УЭК. На нее записан сертификат и закрытый ключ. Есть считыватель. Вручную, при помощи КриптоПро УЭК CSP я могу посмотреть сертификаты в контейнере на УЭК. Могу сохранить этот сертификат в файл на диск.
Требуется программно (автоматически) сделать то же самое: считать сертификат с УЭК и сохранить его на диск. Также необходимо, чтобы в сертификате была проставлена ссылка на закрытый ключ, чтобы из внешнего приложения я мог запустить процесс подписания ЭЦП с помощью этого сертификата.

При помощи CryptAcquireContext получил дескриптор криптопровайдера, получил имя контейнера, а дальше что делать?
Может быть кто-то работал с УЭК программно через CryptoAPI и есть готовые примеры кода?
Offline Андрей Писарев  
#2 Оставлено : 20 мая 2014 г. 11:57:26(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,719
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2054 раз в 1594 постах
Работа с контейнерами\просмотр сертификата и не только: вот здесь есть примеры
Техническую поддержку оказываем тут
Наша база знаний
Offline devyatyarov.andrey  
#3 Оставлено : 20 мая 2014 г. 15:50:18(UTC)
devyatyarov.andrey

Статус: Участник

Группы: Участники
Зарегистрирован: 08.05.2014(UTC)
Сообщений: 12
Мужчина
Российская Федерация

Спасибо за ссылку. Не могу разобраться со следующей ошибкой.
Код с комментариями:

Код:

#include "stdafx.h"
#pragma comment(lib, "crypt32.lib")

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <Wincrypt.h>
#include <iostream>
#include <conio.h>
#include "WinCryptEx.h"

using namespace std;

#define PROV_NAME L"CryptoPro GOST R 34.10-2001 UEC CSP" 
#define CONT_NAME L"UEC-07715ba5-a1c1-47cb-b53f-9157b49c76c3"

int _tmain(int argc, _TCHAR* argv[])
{
        int err;
	HCRYPTPROV hCryptProv;
	BYTE       pbData[1000];        
	DWORD cbData;

	// ********************************
	// Получить дискриптор криптопровайдера
	// ********************************
	if(CryptAcquireContext(
		&hCryptProv, 
		CONT_NAME, 
		PROV_NAME,
		PROV_GOST_2001_DH, 
		CRYPT_UECDATACONTEXT)) //  без этого флага, насколько я понял, взаимодействие с УЭК не будет
	{
		_tprintf(TEXT("CryptAcquireContext succeeded.\n")); // тут все ОК, значит проверку карта прошла и на ней выполнена аутентификация с помощью CV-сертификата средствами КриптоПро УЭК CSP
	}
        // else обработка ошибки

	cbData = 1000;

	// ********************************
	// Установить ПИН
	// ********************************
	int res;
	BYTE bytePIN[5] = { '1', '2', '3', '4', '\0' };
	res = CryptSetProvParam(hCryptProv, PP_UEC_PIN1, bytePIN, 0);
	printf("Rуsult PIN:%d \n", res); // тут все ОК - res возвращает 1

        // else обработка ошибки


	// ********************************
	// Получить двоичные данные ИД-приложения карты УЭК
	// ********************************
	res = CryptGetProvParam(
		hCryptProv, 
		PP_UEC_DATA_BIN, // двоичные данные ИД-приложения карты УЭК
		pbData, 
		&cbData, 
		0);

	if (!res)
	{
		printf("Error PP_UEC_DATA_BIN \n"); 
		err = GetLastError();
		cout << err << endl; // Вот тут выводится ошибка "80100065". Судя по ÷ñÒ880697803êÖ0õæ÷http://msdn.microsoft.com/ru-ru/library/ms936965.aspx÷ñÒ880697803êÖ1õæ÷ : SCARD_W_UNSUPPORTED_CARD "The reader cannot communicate with the card, due to ATR string configuration conflicts."
		_getch();
		exit(1);
	}
	_getch();


Что с этим делать? В какую сторону копать?

Отредактировано пользователем 20 мая 2014 г. 15:50:52(UTC)  | Причина: Не указана

Offline Агафьин Сергей  
#4 Оставлено : 22 мая 2014 г. 14:50:05(UTC)
Grey

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 12.08.2013(UTC)
Сообщений: 834
Мужчина
Российская Федерация
Откуда: Москва

Сказал «Спасибо»: 5 раз
Поблагодарили: 215 раз в 174 постах
Добрый день.
Работа с сертификатом УЭК осуществляется точно также, как и с сертификатами обычных контейнеров. После получения хэндла провайдера (CryptAcquireContext) нужно получить хэндл ключа подписи и сертификат, ассоциированный с данным ключом.

Вот пример кода, который достает сертификат:
Код:

#pragma comment(lib, "advapi32.lib")

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <Wincrypt.h>
#include "WinCryptEx.h"

int _tmain(int argc, TCHAR *argv[]) {
    HCRYPTPROV hProv;
    HCRYPTKEY hKey;
    DWORD cbKeyBlob;		// Длина ключевого BLOBа 
    DWORD cbCertBlob;		// Длина BLOBа сертификата
    TCHAR *szCont;	// Короткое имя контейнера
    BYTE * pbCertBlob;
    if (argc != 2)
	    return 1;

    szCont = argv[1];

    // Получение дескриптора контейнера с именем szCont, 
    if (!CryptAcquireContext(&hProv, szCont, CP_KC1_GR3410_2001_UECFK_PROV, PROV_GOST_2001_DH, 0)) {
	    printf("Error during CryptAcquireContext: %d\n", GetLastError());
	    return 1;
    }

    // Получение дескриптора открытого ключа.
    if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) {
	    CryptReleaseContext(hProv, 0);
	    printf("Error during CryptGetUserKey public key: %d\n", GetLastError());
	    return 1;
    }

    // Получение сертификата ключа из контейнера (если он есть)
    if (!CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &cbCertBlob, 0)) {
	    CryptDestroyKey(hKey);
	    CryptReleaseContext(hProv, 0);
	    printf("Error during CryptGetKeyParam public key: %d\n", GetLastError());
	    return 1;
    }

    pbCertBlob = malloc(cbCertBlob);
    if (!pbCertBlob) {
	    CryptDestroyKey(hKey);
	    CryptReleaseContext(hProv, 0);
	    printf("No memory\n");
	    return 1;
    }

    if (!CryptGetKeyParam(hKey, KP_CERTIFICATE, pbCertBlob, &cbCertBlob, 0)) {
	    free(pbCertBlob);
	    CryptDestroyKey(hKey);
	    CryptReleaseContext(hProv, 0);
	    printf("Error during CryptGetKeyParam public key: %d\n", GetLastError());
	    return 1;
    }

    // сертификат получен, можно его использовать

    printf("Success\n");
    free(pbCertBlob);
    CryptDestroyKey(hKey);
    CryptReleaseContext(hProv, 0);
    return 0;
}

С уважением,
Сергей
Техническую поддержку оказываем здесь.
Наша база знаний.
Offline Андрей Писарев  
#5 Оставлено : 22 мая 2014 г. 15:01:44(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,719
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2054 раз в 1594 постах
Примечание про AT_SIGNATURE и AT_KEYEXCHANGE
Техническую поддержку оказываем тут
Наша база знаний
Offline Kirill Sobolev  
#6 Оставлено : 22 мая 2014 г. 16:14:57(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Цитата:
Примечание про AT_SIGNATURE и AT_KEYEXCHANGE

КриптоПро УЭК CSP, кстати, ключи обмена не поддерживает.
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Кирилл Соболев за этот пост.
Андрей * оставлено 22.05.2014(UTC)
Offline Андрей Писарев  
#7 Оставлено : 22 мая 2014 г. 16:30:01(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,719
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2054 раз в 1594 постах
Автор: Kirill Sobolev Перейти к цитате
Цитата:
Примечание про AT_SIGNATURE и AT_KEYEXCHANGE

КриптоПро УЭК CSP, кстати, ключи обмена не поддерживает.


Это хорошее примечание, про УЭК...
А в коде должен быть анализ наличия AT_SIGNATURE \ AT_KEYEXCHANGE ... Anxious
Техническую поддержку оказываем тут
Наша база знаний
Offline devyatyarov.andrey  
#8 Оставлено : 11 июня 2014 г. 14:35:05(UTC)
devyatyarov.andrey

Статус: Участник

Группы: Участники
Зарегистрирован: 08.05.2014(UTC)
Сообщений: 12
Мужчина
Российская Федерация

Благодарю за предыдущие ответы. В принципе, все получилось реализовать на Си. Теперь предстоит реализовать все это через COM.
Но возникла такая мысль: чтобы не изобретать велосипед, может быть уже где-то есть подобный механизм(считывание сертификата с УЭК) на уровне COM?
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.