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

Уведомление

Icon
Error

3 Страницы123>
Опции
К последнему сообщению К первому непрочитанному
Offline EgorovAlexandr  
#1 Оставлено : 21 августа 2009 г. 15:54:27(UTC)
EgorovAlexandr

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

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

Добрый день. Исходные данные:
есть некоторое сообщение и есть CMS-файл в формате p7b. В файле хранятся сертификат и хэш этого сообщения, подписанного закрытым ключом этого сертификата.

Собственно вопрос:
Как средствами CryptoApi вытащить хэш и сравнить его с хэшем сообщения, подписанного открытым ключем сертификата?

Сертификат выбираю с помощью

hCMSCertStore = CertOpenStore(CERT_STORE_PROV_FILENAME_A,CODE_TYPE, 0,0,"CMS.p7b");
CertFindCertificateInStore(hCMSCertStore,CODE_TYPE,0,CERT_FIND_ANY,NULL,pCertArray);

Заранее спасибо!

З.Ы. это мой первый проект с CryptoApi и в криптографии я пока не силен, так что сразу приношу извинения, если буду тормозить...
Offline ivan.novikov  
#2 Оставлено : 21 августа 2009 г. 18:25:30(UTC)
ivan.novikov

Статус: Активный участник

Группы: Участники
Зарегистрирован: 23.05.2008(UTC)
Сообщений: 74
Откуда: Moscow

Наверное все-так не хэш, а подпись там храниться.
А задача в том, чтобы вытащить из p7b сертификаты и подпись, затем по сертификатам проверить подпись. А само сообщение храниться в отдельном файле.

Средствами Java (КриптоПро JCP) это выглядит следующим образом:
*взято из пример идущих в комплекте с JCP*
Код:

final Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(buffer);
final ContentInfo all = new ContentInfo();
all.decode(asnBuf);

...

if (cms.certificates != null) {
			// Проверка на вложенных сертификатах
			CMStools.logger.info("Validation on certificates founded in CMS.");
			for (int i = 0; i < cms.certificates.elements.length; i++) {
				final Asn1BerEncodeBuffer encBuf = new Asn1BerEncodeBuffer();
				cms.certificates.elements[i].encode(encBuf);
...

for (int j = 0; j < cms.signerInfos.elements.length; j++) {
					System.out.println("Найдена подпись "+j);
					final SignerInfo info = cms.signerInfos.elements[j];

...

Отредактировано пользователем 21 августа 2009 г. 18:29:29(UTC)  | Причина: Не указана

Offline Kirill Sobolev  
#3 Оставлено : 24 августа 2009 г. 14:39:47(UTC)
Кирилл Соболев

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

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

Поблагодарили: 177 раз в 168 постах
Если задача - проверить отсоединенную подпись с помощью CryptoAPI, то лучше не возиться с хэшами и ключами а воспользоваться высокоуровневой функцией CryptVerifyDetachedMessageSignature.
Техническую поддержку оказываем тут
Наша база знаний
Offline EgorovAlexandr  
#4 Оставлено : 24 августа 2009 г. 14:48:05(UTC)
EgorovAlexandr

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

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

Основной проблемой является не само сравнение подписей, а возможность получить эту подпись из файла стандартными средствами CryptoApi. В настоящий момент для получения подписи приходится с помощью dumpasn1 парсить p7b файл в некоторый временный файл, а потом из временного файла уже вытаскивать подпись. Хотелось бы уйти от такого варианта...
Offline Kirill Sobolev  
#5 Оставлено : 24 августа 2009 г. 17:22:40(UTC)
Кирилл Соболев

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

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

Поблагодарили: 177 раз в 168 постах
посмотрите функции CryptMsg*
Техническую поддержку оказываем тут
Наша база знаний
Offline EgorovAlexandr  
#6 Оставлено : 25 августа 2009 г. 16:29:58(UTC)
EgorovAlexandr

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

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

Отредактировано пользователем 25 августа 2009 г. 16:45:37(UTC)  | Причина: Не указана

Offline Kirill Sobolev  
#7 Оставлено : 25 августа 2009 г. 16:47:51(UTC)
Кирилл Соболев

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

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

Поблагодарили: 177 раз в 168 постах
Без закрытого ключа инициализировать провайдер не так просто - нужно перебрать все и посмотреть, какой именно поддерживает алгоритм открытого ключа из сертификата. Их кстати может быть несколько. Но для работы с высокоуровневыми функциями обычно такая операция не требуется.
Техническую поддержку оказываем тут
Наша база знаний
Offline EgorovAlexandr  
#8 Оставлено : 25 августа 2009 г. 18:27:54(UTC)
EgorovAlexandr

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

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

Пытаюсь использовать функцию CryptVerifyDetachedMessageSignature следующим образом:
Код:

CRYPT_VERIFY_MESSAGE_PARA msgPara;

msgPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
msgPara.dwMsgAndCertEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
msgPara.hCryptProv = NULL;
msgPara.pfnGetSignerCertificate = NULL;
msgPara.pvGetArg = NULL;

if( !CryptVerifyDetachedMessageSignature(
                                         &msgPara, //указатель на структуру
                                         1, //индекс подписи, которую надо проверить
                                         hexSig, //собственно подпись в шестнадцатиричном виде
                                         cSig, //размер подписи
                                         1, //количество элементов в массивах следующих параметров
                                         &pbContent, //сообщение в открытом виде
                                         &cbContent, //длина сообщения 
                                         NULL //указатель на сертификат. Параметр опционален, потому не вызываю
                                         ) )
{
	printf("%x\n",GetLastError());
}


Этот пример взял из MSDN http://msdn.microsoft.co...ary/aa381076(VS.85).aspx

При выполнении получаю ошибку 0x8009310b. Расшифровка ошибки -- "Встречено неверное значение тега ASN1." (если я правильно нашел).
Еще пытался передавать в msgPara.pfnGetSignerCertificate указатель на Callback-функцию CryptGetSignerCertificateCallback(), но не могу корректно записать msgPara.pvGetArg

Отредактировано пользователем 25 августа 2009 г. 18:34:13(UTC)  | Причина: Не указана

Offline Flame_xXx  
#9 Оставлено : 25 августа 2009 г. 18:46:09(UTC)
Flame_xXx

Статус: Активный участник

Группы: Участники
Зарегистрирован: 27.10.2008(UTC)
Сообщений: 63

пробовали msgPara обнулять?
ZeroMemory(&msgPara, sizeof(msgPara));
Возможно у Вас битый сертификат

Отредактировано пользователем 25 августа 2009 г. 19:55:18(UTC)  | Причина: Не указана

Offline Kirill Sobolev  
#10 Оставлено : 25 августа 2009 г. 18:49:20(UTC)
Кирилл Соболев

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

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

Поблагодарили: 177 раз в 168 постах
Цитата:
При выполнении получаю ошибку 0x8009310b. Расшифровка ошибки -- "Встречено неверное значение тега ASN1."

CryptVerifyDetachedMessageSignature понимает только бинарные данные. Что такое "подпись в шестнадцатиричном виде"?
Цитата:
не могу корректно записать msgPara.pvGetArg

Там может быть любой указатель на что угодно. Что именно Вы хотите передать в CryptGetSignerCertificateCallback в этом параметре?
Техническую поддержку оказываем тут
Наша база знаний
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
3 Страницы123>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.