Статус: Участник
Группы: Участники
Зарегистрирован: 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 и в криптографии я пока не силен, так что сразу приношу извинения, если буду тормозить...
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 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)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 25.12.2007(UTC) Сообщений: 1,732 Откуда: КРИПТО-ПРО Поблагодарили: 177 раз в 168 постах
|
Если задача - проверить отсоединенную подпись с помощью CryptoAPI, то лучше не возиться с хэшами и ключами а воспользоваться высокоуровневой функцией CryptVerifyDetachedMessageSignature. |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 21.08.2009(UTC) Сообщений: 21 Откуда: Москва
|
Основной проблемой является не само сравнение подписей, а возможность получить эту подпись из файла стандартными средствами CryptoApi. В настоящий момент для получения подписи приходится с помощью dumpasn1 парсить p7b файл в некоторый временный файл, а потом из временного файла уже вытаскивать подпись. Хотелось бы уйти от такого варианта...
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 25.12.2007(UTC) Сообщений: 1,732 Откуда: КРИПТО-ПРО Поблагодарили: 177 раз в 168 постах
|
посмотрите функции CryptMsg* |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 21.08.2009(UTC) Сообщений: 21 Откуда: Москва
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 25.12.2007(UTC) Сообщений: 1,732 Откуда: КРИПТО-ПРО Поблагодарили: 177 раз в 168 постах
|
Без закрытого ключа инициализировать провайдер не так просто - нужно перебрать все и посмотреть, какой именно поддерживает алгоритм открытого ключа из сертификата. Их кстати может быть несколько. Но для работы с высокоуровневыми функциями обычно такая операция не требуется. |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 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)
| Причина: Не указана
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 27.10.2008(UTC) Сообщений: 63
|
пробовали msgPara обнулять? ZeroMemory(&msgPara, sizeof(msgPara)); Возможно у Вас битый сертификат Отредактировано пользователем 25 августа 2009 г. 19:55:18(UTC)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 25.12.2007(UTC) Сообщений: 1,732 Откуда: КРИПТО-ПРО Поблагодарили: 177 раз в 168 постах
|
Цитата:При выполнении получаю ошибку 0x8009310b. Расшифровка ошибки -- "Встречено неверное значение тега ASN1." CryptVerifyDetachedMessageSignature понимает только бинарные данные. Что такое "подпись в шестнадцатиричном виде"? Цитата:не могу корректно записать msgPara.pvGetArg Там может быть любой указатель на что угодно. Что именно Вы хотите передать в CryptGetSignerCertificateCallback в этом параметре? |
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close