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

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline andreyxvo  
#1 Оставлено : 3 февраля 2012 г. 12:48:32(UTC)
andreyxvo

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

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

Здравствуйте.
Помогите пожалуйста! Вроде бы простая задачка. Есть ЭЦП, содержащая соподписи. Создается и проверяется все хорошо. Но вдруг один из подписавшихся решит отозвать свою подпись... Возможно ли "выковырять" его подпись, так чтоб други там остались. Если возможно то как?

Спасибо.

Соподписи делаю следующим образом:
Код:

bool CoSignMessage(PCCERT_CONTEXT *a_CertContext, // Сертификат
				   CRYPT_DATA_BLOB *pSignedMessageBlob, // уже подписаное сообщение
				   CRYPT_DATA_BLOB *pCosignedMessageBlob, // результат - соподписаное сообщение
				   LPSTR sMsg )
{
	bool fReturn = false; 
	PCCERT_CONTEXT pCosignerCert = *a_CertContext; 
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTMSG hMsg = NULL;
	DWORD cbCosignedMessageBlob;
	BYTE  *pbCosignedMessageBlob = NULL;


	// Initialize the output pointer.
	pCosignedMessageBlob->cbData = 0;
	pCosignedMessageBlob->pbData = NULL;
	DWORD dwKeySpec;
	if(!(CryptAcquireCertificatePrivateKey(
		pCosignerCert,
		0,
		NULL,
		&hCryptProv,
		&dwKeySpec,
		NULL)))
	{
		MyHandleError(
			TEXT("CryptAcquireCertificatePrivateKey failed."));
		 exit_CosignMessage(hMsg, pbCosignedMessageBlob);
	}

	// Open a message for decoding.
	if(!(hMsg = CryptMsgOpenToDecode(
		m_Encoding_Type, //MY_ENCODING_TYPE,
		0,//CMSG_DETACHED_FLAG,
		0,
		NULL,
		NULL,
		NULL)))
	{
		MyHandleError(TEXT("CryptMsgOpenToDecode failed."));
		exit_CosignMessage(hMsg, pbCosignedMessageBlob);
	}


	// Update the message with the encoded BLOB.
	if(!(CryptMsgUpdate(
		hMsg,
		pSignedMessageBlob->pbData,
		pSignedMessageBlob->cbData,
		TRUE)))
	{
		MyHandleError(TEXT("CryptMsgUpdate failed."));
		exit_CosignMessage(hMsg, pbCosignedMessageBlob);
	}

	// Initialize the CMSG_SIGNER_ENCODE_INFO structure for the 
	// cosigner.
	CMSG_SIGNER_ENCODE_INFO CosignerInfo;
	memset(&CosignerInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
	CosignerInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
	CosignerInfo.pCertInfo = pCosignerCert->pCertInfo;//*a_pCertContext->pCertInfo;
	CosignerInfo.hCryptProv = hCryptProv;
	CosignerInfo.dwKeySpec = dwKeySpec;
	CosignerInfo.HashAlgorithm.pszObjId = m_HashAlgorithm;//szOID_RSA_SHA1RSA;



	// Add the cosigner to the message.
	if(CryptMsgControl(
		hMsg,
		0,
		CMSG_CTRL_ADD_SIGNER,
		&CosignerInfo))
	{
		_tprintf(TEXT("CMSG_CTRL_ADD_SIGNER succeeded. \n"));
	}
	else
	{
		MyHandleError(TEXT("CMSG_CTRL_ADD_SIGNER failed."));
		exit_CosignMessage(hMsg, pbCosignedMessageBlob);
	}

	// Add the cosigner's certificate to the message.
	CERT_BLOB CosignCertBlob;
	CosignCertBlob.cbData = pCosignerCert->cbCertEncoded;
	CosignCertBlob.pbData = pCosignerCert->pbCertEncoded;

	if(CryptMsgControl(
		hMsg,
		0,
		CMSG_CTRL_ADD_CERT,
		&CosignCertBlob))
	{
		_tprintf(TEXT("CMSG_CTRL_ADD_CERT succeeded. \n"));
	}
	else
	{
		MyHandleError(TEXT("CMSG_CTRL_ADD_CERT failed."));
		exit_CosignMessage(hMsg, pbCosignedMessageBlob);
	}

	// Get the size of the cosigned BLOB.
	if(CryptMsgGetParam(
		hMsg,
		CMSG_ENCODED_MESSAGE,
		0,
		NULL,
		&cbCosignedMessageBlob))
	{
		_tprintf(TEXT("The size for the encoded BLOB is %d.\n"), 
			cbCosignedMessageBlob);
	}
	else
	{
		MyHandleError(TEXT("Sizing of cbSignerInfo failed."));
		exit_CosignMessage(hMsg, pbCosignedMessageBlob);
	}

	// Allocate memory for the cosigned BLOB.
	if(!(pbCosignedMessageBlob = 
		(BYTE*)malloc(cbCosignedMessageBlob)))
	{
		MyHandleError(
			TEXT("Memory allocation error while cosigning."));
		exit_CosignMessage(hMsg, pbCosignedMessageBlob);
	}

	// Get the cosigned message BLOB.
	if(CryptMsgGetParam(
		hMsg,
		CMSG_ENCODED_MESSAGE,
		0,
		pbCosignedMessageBlob,
		&cbCosignedMessageBlob))
	{
		_tprintf(TEXT("The message was cosigned successfully. \n"));

		// pbSignedMessageBlob now contains the signed BLOB.
		fReturn = true;
	}
	else
	{
		MyHandleError(TEXT("Sizing of cbSignerInfo failed."));
		exit_CosignMessage(hMsg, pbCosignedMessageBlob);
	}

	if(pbCosignedMessageBlob)
	{
		pCosignedMessageBlob->cbData = cbCosignedMessageBlob;
		pCosignedMessageBlob->pbData = pbCosignedMessageBlob;
	}

	return fReturn;
}

bool exit_CosignMessage(HCRYPTMSG hMsg, BYTE  *pbCosignedMessageBlob = NULL,  bool fReturn=false)
{
	// Only free the signed message if a failure ocurred.
	if(!fReturn)
	{	
		if(hMsg)
		{
			CryptMsgClose(hMsg);
		}
		if(pbCosignedMessageBlob)
		{
			free(pbCosignedMessageBlob);
			pbCosignedMessageBlob = NULL;
		}
	}
	return 	fReturn;
}

Offline Kirill Sobolev  
#2 Оставлено : 3 февраля 2012 г. 13:19:00(UTC)
Кирилл Соболев

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

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

Поблагодарили: 177 раз в 168 постах
CryptMsgControl(.., CMSG_CTRL_ADD_SIGNER, ..) - добавить подпись.
CryptMsgControl(.., CMSG_CTRL_DEL_SIGNER, ..) - удалить подпись.
Техническую поддержку оказываем тут
Наша база знаний
Offline andreyxvo  
#3 Оставлено : 13 февраля 2012 г. 19:42:05(UTC)
andreyxvo

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

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

Что то я забуксовал с удалением подписи.
CryptMsgControl(
__in HCRYPTMSG hCryptMsg, <----- здесь
__in DWORD dwFlags, <----- всё
__in DWORD dwCtrlType, <----- понятно
__in const void* pvCtrlPara <------------------- Ни как не соображу что делать с этим параметром... :(
)


Если правильно понимаю, что этот параметр CMSG_CTRL_DEL_SIGNER_(UN)AUTH_ATTR_PARA данные в который получить из зараннее положеных в подпись
парамеров, которые у меня нулевые:
CRYPT_SIGN_MESSAGE_PARA SigParams;
SigParams.cAuthAttr = 0;
SigParams.rgAuthAttr = NULL;
SigParams.cUnauthAttr = 0;
SigParams.rgUnauthAttr = NULL;

Если так, то ни как не соображу как положить эти параметры.

Предполагаю что:
PCRYPT_ATTRIBUTE pAttr;
pAttr->pszObjId = Какой нужен OID?
pAttr->cValue = <---Это понятно даже мне...
pAttr->rgValue = <--- видимо это CRYPT_ATTR_BLOB

Offline Андрей Писарев  
#4 Оставлено : 13 февраля 2012 г. 19:52:31(UTC)
Андрей *

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

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

Сказал «Спасибо»: 549 раз
Поблагодарили: 2201 раз в 1717 постах
andreyxvo написал:
Что то я забуксовал с удалением подписи.
CryptMsgControl(
__in HCRYPTMSG hCryptMsg, <----- здесь
__in DWORD dwFlags, <----- всё
__in DWORD dwCtrlType, <----- понятно
__in const void* pvCtrlPara <------------------- Ни как не соображу что делать с этим параметром... :(
)


Если правильно понимаю, что этот параметр CMSG_CTRL_DEL_SIGNER_(UN)AUTH_ATTR_PARA данные в который получить из зараннее положеных в подпись
парамеров, которые у меня нулевые:
CRYPT_SIGN_MESSAGE_PARA SigParams;
SigParams.cAuthAttr = 0;
SigParams.rgAuthAttr = NULL;
SigParams.cUnauthAttr = 0;
SigParams.rgUnauthAttr = NULL;

Если так, то ни как не соображу как положить эти параметры.

Предполагаю что:
PCRYPT_ATTRIBUTE pAttr;
pAttr->pszObjId = Какой нужен OID?
pAttr->cValue = <---Это понятно даже мне...
pAttr->rgValue = <--- видимо это CRYPT_ATTR_BLOB






если
Цитата:
__in DWORD dwCtrlType, <----- понятно

тогда:

http://msdn.microsoft.co...us/library/ms938247.aspx

Отредактировано пользователем 13 февраля 2012 г. 19:53:26(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline andreyxvo  
#5 Оставлено : 13 февраля 2012 г. 20:22:31(UTC)
andreyxvo

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

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

Здесь написано следующее: "CMSG_CTRL_DEL_SIGNER The index of the signer to be deleted." Моя проблема в том, что ни как не соображу где взять этот индекс.

Скорее всего при создании подписи:

CRYPT_ATTRIBUTE pAttr;
.....

CRYPT_SIGN_MESSAGE_PARA SigParams;
SigParams.cAuthAttr = 1;
SigParams.rgAuthAttr = "Сюда что засунуть????";

Наверно:
PCRYPT_ATTRIBUTE pAttr;
pAttr->pszObjId = ????????
pAttr->cValue = размер блоба
pAttr->rgValue = что за блоб здесь должен валяться?

где pAttr->rgValue=
CRYPT_DATA_BLOB pSigAttrBlob;
pSigAttrBlob.cbData = размер;
pSigAttrBlob.pbData = что-то. Что именно надо положить?
Или я ушел не в те дебри....

Отредактировано пользователем 13 февраля 2012 г. 20:30:56(UTC)  | Причина: Не указана

Offline Андрей Писарев  
#6 Оставлено : 13 февраля 2012 г. 20:31:24(UTC)
Андрей *

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

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

Сказал «Спасибо»: 549 раз
Поблагодарили: 2201 раз в 1717 постах
andreyxvo написал:
Здесь написано следующее: "CMSG_CTRL_DEL_SIGNER The index of the signer to be deleted." Моя проблема в том, что ни как не соображу где взять этот индекс.

Скорее всего при создании подписи:

CRYPT_ATTRIBUTE pAttr;
.....

CRYPT_SIGN_MESSAGE_PARA SigParams;
SigParams.cAuthAttr = 1;
SigParams.rgAuthAttr = "Сюда что засунуть????";

Наверно:
CRYPT_DATA_BLOB pSigAttrBlob;
pSigAttrBlob.cbData = размер;
pSigAttrBlob.pbData = что-то. Что именно надо положить?
Или я ушел не в те дебри....



так при проверке же... читаем в цикле ... знаем сколько подписантов, индекс текущего, проверка текущей [i] ЭЦП ...
где-то запоминаем\показываем в GUI для пользователя, он может выбрать нужную ЭЦП [i] и исключить ее...

Отредактировано пользователем 13 февраля 2012 г. 20:32:25(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline andreyxvo  
#7 Оставлено : 14 февраля 2012 г. 14:44:30(UTC)
andreyxvo

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

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

ЧТо-то начало получаться. Алгоритм такой:
Код:


CryptMsgUpdate(hMsg, pSignedMessageBlob->pbData, pSignedMessageBlob->cbData, TRUE)
for(LONG i = 0; i < lSigners; i++)
{
     if(!(CryptVerifyMessageSignature(&VerifyParams, i,  pCosignedMessageBlob->pbData,pCosignedMessageBlob->cbData...)
     if (i == нужное значение)
        {
            if(CryptMsgControl(hMsg,0, CMSG_CTRL_DEL_SIGNER,&i))     
               //получаю подписаное сообщение с помощью двойного вызова ф-и
            if(CryptMsgGetParam(hMsg, CMSG_ENCODED_MESSAGE....)
            
           //выхожу из цикла
         }
}
 CryptMsgClose(hMsg);
......

//при проверке lSigners = 0
LONG lSigners = CryptGetMessageSignerCount(	MY_ENCODING_TYPE, pCosignedMessageBlob->pbData, 	pCosignedMessageBlob->cbData);




Процесс удаления, ошибок не выкидывает.
Но при проверке подписи, выясняется, что количество подписантов равно 0. Хотя изначально оно было равно 2, а после удаления одного подписанта, должно стать равной 1.

Отредактировано пользователем 14 февраля 2012 г. 15:06:34(UTC)  | Причина: Не указана

Offline Андрей Писарев  
#8 Оставлено : 14 февраля 2012 г. 16:52:10(UTC)
Андрей *

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

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

Сказал «Спасибо»: 549 раз
Поблагодарили: 2201 раз в 1717 постах
andreyxvo написал:
ЧТо-то начало получаться. Алгоритм такой:
Код:


CryptMsgUpdate(hMsg, pSignedMessageBlob->pbData, pSignedMessageBlob->cbData, TRUE)
for(LONG i = 0; i < lSigners; i++)
{
     if(!(CryptVerifyMessageSignature(&VerifyParams, i,  pCosignedMessageBlob->pbData,pCosignedMessageBlob->cbData...)
     if (i == нужное значение)
        {
            if(CryptMsgControl(hMsg,0, CMSG_CTRL_DEL_SIGNER,&i))     
               //получаю подписаное сообщение с помощью двойного вызова ф-и
            if(CryptMsgGetParam(hMsg, CMSG_ENCODED_MESSAGE....)
            
           //выхожу из цикла
         }
}
 CryptMsgClose(hMsg);
......

//при проверке lSigners = 0
LONG lSigners = CryptGetMessageSignerCount(	MY_ENCODING_TYPE, pCosignedMessageBlob->pbData, 	pCosignedMessageBlob->cbData);




Процесс удаления, ошибок не выкидывает.
Но при проверке подписи, выясняется, что количество подписантов равно 0. Хотя изначально оно было равно 2, а после удаления одного подписанта, должно стать равной 1.



краткое ТЗ: Anxious

дано: 2 ЭЦП
Делаем проверку ЭЦП (можно и без нее отобразить кол-во подписей\подписантов\сертификатов)

отображаем пользователю в интерфейсе список ЭЦП ..

получаем команду от пользователя удалить одну из ЭЦП

удаляем первую: index:=0;





Отредактировано пользователем 14 февраля 2012 г. 17:13:24(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей Писарев  
#9 Оставлено : 14 февраля 2012 г. 17:25:31(UTC)
Андрей *

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

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

Сказал «Спасибо»: 549 раз
Поблагодарили: 2201 раз в 1717 постах
что-то сегодня форум зависает сильно...

итак: есть файл с отсоединенной ЭЦП
вызываем
CryptQueryObject (.. hMsg ..)
CryptMsgGetParam(hMsg, CMSG_SIGNER_COUNT_PARAM...
CryptMsgGetParam(hMsg, CMSG_SIGNER_COUNT_PARAM.. pdwCount

pdwCount = кол-во подписей

CryptMsgControl(hMsg,0, CMSG_CTRL_DEL_SIGNER,@index);
CryptMsgGetParam( hMsg, CMSG_ENCODED_MESSAGE, cbEncodedBlob .. nil)
CryptMsgGetParam( hMsg, CMSG_ENCODED_MESSAGE, cbEncodedBlob .. pbEncodedBlob)

итого:

в pbEncodedBlob есть blob с новым набором ЭЦП исключая указанную
сохраняем в файл...
радуемся, идем на обед..

все..

p.s.
домашнее задание
добавить проверки\выделение памяти\логирование и т.д.
интерфейс пользователя - на усмотрение...

Отредактировано пользователем 14 февраля 2012 г. 17:27:09(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline andreyxvo  
#10 Оставлено : 14 февраля 2012 г. 18:18:01(UTC)
andreyxvo

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

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

Большое спасибо!!! я слишком далеко забрался в дебри. Оказалось все намного проще чем я себе вообразил.

Вот функция, учебная, которая отзывает подпись. Вроде работает. КриптоАРМ проверяет, показывает одного подписанта.
Может кому-то поможет.

Код:

bool DeCosignMessage(   CRYPT_DATA_BLOB *pCosignedMessageBlob  )
{
	bool fReturn = false;
	//BYTE *pbDecodedMessage = NULL;

	
	LONG lSigners = CryptGetMessageSignerCount(
		MY_ENCODING_TYPE, 
		pCosignedMessageBlob->pbData, 
		pCosignedMessageBlob->cbData);
	if(-1 == lSigners)
	{
		MyHandleError(TEXT("CryptGetMessageSignerCount failed."));
		return false;
	}
	HCRYPTMSG hMsg = NULL;
	if(!(hMsg = CryptMsgOpenToDecode(
		MY_ENCODING_TYPE,
		0,
		0,
		NULL,
		NULL,
		NULL)))
	{
		MyHandleError(TEXT("CryptMsgOpenToDecode failed."));
		return false;
	}
	if(!(CryptMsgUpdate(
		hMsg,
		pCosignedMessageBlob->pbData,
		pCosignedMessageBlob->cbData,
		TRUE)))
	{
		MyHandleError(TEXT("CryptMsgUpdate failed."));
		return false;
	}

	int index=0; // !!!! Удаляю первую подпись !!!!

	//--- Удаляю первого подписанта  --- 
	if (!CryptMsgControl(hMsg,0, CMSG_CTRL_DEL_SIGNER,&index))
	{
		MyHandleError(TEXT("CMSG_CTRL_DEL_SIGNER failed."));
		
	}

    // получаю исправленую подпись


	free(pCosignedMessageBlob->pbData);
	pCosignedMessageBlob->pbData = NULL;
	pCosignedMessageBlob->cbData = 0;
	if(CryptMsgGetParam(
		hMsg,
		CMSG_ENCODED_MESSAGE,
		0,
		NULL,
		&pCosignedMessageBlob->cbData))
	{
		_tprintf(TEXT("The size for the encoded BLOB is %d.\n"),pCosignedMessageBlob->cbData);		
	}
	else
	{
		MyHandleError(TEXT("Sizing of cbSignerInfo failed."));
		return false;
	}
	

	if(!(pCosignedMessageBlob->pbData = 
		(BYTE*)malloc(pCosignedMessageBlob->cbData)))
	{
		MyHandleError(
			TEXT("Memory allocation error while cosigning."));
		return false;
	}

	// Get the cosigned message BLOB.
	if(CryptMsgGetParam(
		hMsg,
		CMSG_ENCODED_MESSAGE,
		0,
		pCosignedMessageBlob->pbData,
		&pCosignedMessageBlob->cbData))
	{
		_tprintf(TEXT("The message was cosigned successfully. \n"));
		
		// pbSignedMessageBlob now contains the signed BLOB.
		/*goto exit_VerifyCosignedMessage;*/
	}
	else
	{
		MyHandleError(TEXT("Sizing of cbSignerInfo failed."));
		fReturn = true; //goto exit_VerifyCosignedMessage;
	}
	
 	// смотрю сколько подписантов осталось.
	LONG lSigners1 = CryptGetMessageSignerCount(
		MY_ENCODING_TYPE, 
		pCosignedMessageBlob->pbData, 
		pCosignedMessageBlob->cbData);
    
	if(0 == lSigners1)
	{
		MessageBox(NULL,"Нет подписантов.", "Ошибка!!!!", MB_OK	);
	}
	if(hMsg)
	{
		CryptMsgClose(hMsg);
	}
 	


	return fReturn;
}

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