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

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline nex-54  
#1 Оставлено : 8 декабря 2011 г. 13:59:49(UTC)
nex-54

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

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

Сказал «Спасибо»: 1 раз
Добрый день!
С подписями раньше не работал - опыта нет.
Имеется пара вопросов по работе с УЭЦП в C#

1) При проверке УЭЦП, мы ведь должны указывать адрес OCSP сервера?
В примерах и в обсуждениях не нашел, где он указывается.

2) Что такое "параллельная подпись"?

3) Почему на момент проверки УЭЦП должен быть действительным сертификат TSP сервера?

5) Чем отличаются CAdES BES и CAdES X Long Type 1?

6) Где можно прочитать, что такое CMS-сообщение, кроме как тут http://www.ietf.org/rfc/rfc3852.txt?

Спасибо за ответ.

Отредактировано пользователем 8 декабря 2011 г. 16:33:57(UTC)  | Причина: Не указана

Offline Новожилова Елена  
#2 Оставлено : 12 декабря 2011 г. 21:06:20(UTC)
Новожилова Елена

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

Группы: Администраторы, Участники
Зарегистрирован: 10.12.2008(UTC)
Сообщений: 924
Женщина
Откуда: Крипто-Про

Поблагодарили: 99 раз в 95 постах
1. Адрес OCSP должен быть указан либо в расширении AIA сертификата, либо задан в групповой политике КриптоПро OCSP Client: адрес службы OCSP по умолчанию.

2. Параллельные полписи - это несколько структур SignerInfo в одном сообщении.

3. См. ETSI TS 101 733 (CAdES).

5. Аналогично п.3.

6. Вот здесь http://www.ietf.org/rfc/rfc5652.txt :-)

Отредактировано пользователем 12 декабря 2011 г. 21:07:05(UTC)  | Причина: Не указана

Offline andreyxvo  
#3 Оставлено : 16 января 2012 г. 18:46:53(UTC)
andreyxvo

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

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

Здравтствуйте!!!!

Может подскажите? Как сделать эту "параллельную подпись" с помощью CryptoApi?

Большое Пожалуйста!!!!!

Нужно хотя бы "Эскизное" описание алгоритма.

Задача уже существующую (присоединенную/отсоединенную) подпись дополнить подписью еще одного лица.

Обычную подпись делаю с помощью кода:
Код:

/ Создает отдельную от сообщения ЭЦП. 
bool CreateSignature_int(PCCERT_CONTEXT a_pCertContext, BYTE* pbContent, CRYPT_DATA_BLOB *pSignatureBlob)
{
	//const BYTE* pbContent = (BYTE*)"Test Message.";

	DWORD cbContent;               // Size of message
	HCRYPTPROV hCryptProv;         // CSP handle

	CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
	CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
	CERT_BLOB SignerCertBlob;
	CERT_BLOB SignerCertBlobArray[1];
	CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
	DWORD cbEncodedBlob;
	BYTE* pbEncodedBlob;
	HCRYPTMSG hMsg;
	DWORD dwKeySpec;

	//CRYPT_VERIFY_MESSAGE_PARA msgPara;

	//---------------------------------------------------------------
	//  Initialize cbContent to the length of pbContent
	//  including the terminating NULL character.
	cbContent = strlen((char *) pbContent)+1;

	//---------------------------------------------------------------
	// Get a handle to a cryptographic provider. 
	if( !(CryptAcquireCertificatePrivateKey(
		a_pCertContext,
		0,
		NULL,
		&hCryptProv,
		&dwKeySpec,
		NULL)))
	{
		MyHandleError(_T("CryptAcquireContext failed"));		
		return FALSE;
	}

	memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
	SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
	SignerEncodeInfo.pCertInfo = a_pCertContext->pCertInfo;
	SignerEncodeInfo.hCryptProv = hCryptProv;
	SignerEncodeInfo.dwKeySpec = dwKeySpec;
	SignerEncodeInfo.HashAlgorithm.pszObjId = m_HashAlgorithm;
	SignerEncodeInfo.pvHashAuxInfo = NULL;

	//---------------------------------------------------------------
	// Initialize the first element of an array of signers. 
	// Note: Currently, there is only one signer.
	SignerEncodeInfoArray[0] = SignerEncodeInfo;

	//---------------------------------------------------------------
	// Initialize the CMSG_SIGNED_ENCODE_INFO structure.
	SignerCertBlob.cbData = a_pCertContext->cbCertEncoded;
	SignerCertBlob.pbData = a_pCertContext->pbCertEncoded;

	//---------------------------------------------------------------
	//  Initialize the first element of an array of signer BLOBs.
	//  Note: In this program, only one signer BLOB is used.

	SignerCertBlobArray[0] = SignerCertBlob;
	memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
	SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
	SignedMsgEncodeInfo.cSigners = 1;
	SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
	SignedMsgEncodeInfo.cCertEncoded = 1;
	SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;

	//---------------------------------------------------------------
	// Get the size of the encoded message BLOB.
	if(!(cbEncodedBlob = CryptMsgCalculateEncodedLength(
		m_Encoding_Type,     // Message encoding type
		0,                    // Flags
		CMSG_SIGNED,          // Message type
		&SignedMsgEncodeInfo, // Pointer to structure
		NULL,                 // Inner content OID
		cbContent)))          // Size of content
	{
		MyHandleError(_T("Getting cbEncodedBlob length failed."));		
		return FALSE;
	}

	//---------------------------------------------------------------
	// Allocate memory for the encoded BLOB.
	if(!(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob)))
	{
		MyHandleError(_T("Malloc operation failed."));
		exit_CreateSign(NULL, hCryptProv, pbEncodedBlob);
		return FALSE;
	}

	//---------------------------------------------------------------
	// Open a message to encode.
	if(!(hMsg = CryptMsgOpenToEncode(
		m_Encoding_Type,       // Encoding type
		CMSG_DETACHED_FLAG,    // Flags
		CMSG_SIGNED,           // Message type
		&SignedMsgEncodeInfo,  // Pointer to structure
		NULL,                  // Inner content OID
		NULL)))                // Stream information (not used)
	{
		MyHandleError(_T("OpenToEncode failed"));
		exit_CreateSign(hMsg, hCryptProv, pbEncodedBlob);
		return FALSE;
	}

	//---------------------------------------------------------------
	// Update the message with the data.
	if(!(CryptMsgUpdate(
		hMsg,       // Handle to the message
		pbContent,  // Pointer to the content
		cbContent,  // Size of the content
		TRUE)))     // Last call
	{
		MyHandleError(_T("MsgUpdate failed"));
		exit_CreateSign(hMsg, hCryptProv, pbEncodedBlob);
		return FALSE;
	}

	//---------------------------------------------------------------
	// Get the resulting message.	
	if(!CryptMsgGetParam(
		hMsg,               // Handle to the message
		CMSG_CONTENT_PARAM, // Parameter type
		0,                  // Index
		pbEncodedBlob,      // Pointer to the BLOB
		&cbEncodedBlob))    // Size of the BLOB
	{
		MyHandleError(_T("MsgGetParam failed."));
		exit_CreateSign(hMsg, hCryptProv, pbEncodedBlob);
		return FALSE;
	}
	pSignatureBlob->cbData = cbEncodedBlob;
	pSignatureBlob->pbData = pbEncodedBlob;

	//---------------------------------------------------------------
	// The message is signed and encoded.
	// Close the message handle and the certificate store.
	CryptMsgClose(hMsg);
	CryptReleaseContext(hCryptProv, 0);
	return TRUE;
}


Присоединную подпись делаю с помощью функции:
Код:

bool SignMessage( PCCERT_CONTEXT *a_pCertContext, CRYPT_DATA_BLOB *pSignedMessageBlob, LPSTR sMsg )
{
	bool fReturn = false;
	BYTE* pbMessage;
	DWORD cbMessage;
	HCERTSTORE hCertStore = NULL;   
	//PCCERT_CONTEXT pSignerCert; 
	CRYPT_SIGN_MESSAGE_PARA  SigParams;
	DWORD cbSignedMessageBlob;
	BYTE  *pbSignedMessageBlob = NULL;

	// Initialize the output pointer.
	pSignedMessageBlob->cbData = 0;
	pSignedMessageBlob->pbData = NULL;

	// The message to be signed.
	// Usually, the message exists somewhere and a pointer is
	// passed to the application.
	pbMessage = 
		(BYTE*) sMsg; //TEXT("The message: CryptoAPI is a good way to handle security.");

	// Calculate the size of message. To include the 
	// terminating null character, the length is one more byte 
	// than the length returned by the strlen function.
	cbMessage = (lstrlen((TCHAR*) pbMessage) + 1) * sizeof(TCHAR);

	// Create the MessageArray and the MessageSizeArray.
	const BYTE* MessageArray[] = {pbMessage};
	DWORD_PTR MessageSizeArray[1];
	MessageSizeArray[0] = cbMessage;

	//  Begin processing. 
// 	_tprintf(TEXT("The message to be signed is \"%s\".\n"),
// 		pbMessage);

	// Initialize the signature structure.
	SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
	SigParams.dwMsgEncodingType = m_Encoding_Type;
	SigParams.pSigningCert = *a_pCertContext;
	SigParams.HashAlgorithm.pszObjId = m_HashAlgorithm;
	SigParams.HashAlgorithm.Parameters.cbData = NULL;
	SigParams.cMsgCert = 1;
	SigParams.rgpMsgCert = a_pCertContext;
	SigParams.cAuthAttr = 0;
	SigParams.dwInnerContentType = 0;
	SigParams.cMsgCrl = 0;
	SigParams.cUnauthAttr = 0;
	SigParams.dwFlags = 0;
	SigParams.pvHashAuxInfo = NULL;
	SigParams.rgAuthAttr = NULL;

	// First, get the size of the signed BLOB.
	if(CryptSignMessage(
		&SigParams,
		FALSE,
		1,
		MessageArray,
		MessageSizeArray,
		NULL,
		&cbSignedMessageBlob))
	{
// 		_tprintf(TEXT("%d bytes needed for the encoded BLOB.\n"),
// 			cbSignedMessageBlob);
	}
	else
	{
		MyHandleError(TEXT("Getting signed BLOB size failed"));
		exit_SignMessage(pbSignedMessageBlob); 
		return fReturn;
	}

	// Allocate memory for the signed BLOB.
	if(!(pbSignedMessageBlob = 
		(BYTE*)malloc(cbSignedMessageBlob)))
	{
		MyHandleError(
			TEXT("Memory allocation error while signing."));
		exit_SignMessage(pbSignedMessageBlob);
		return fReturn;
	}

	// Get the signed message BLOB.
	if(CryptSignMessage(
		&SigParams,
		FALSE,
		1,
		MessageArray,
		MessageSizeArray,
		pbSignedMessageBlob,
		&cbSignedMessageBlob))
	{
		//_tprintf(TEXT("The message was signed successfully. \n"));
		// pbSignedMessageBlob now contains the signed BLOB.
		fReturn = true;
		if(pbSignedMessageBlob)
		{
			pSignedMessageBlob->cbData = cbSignedMessageBlob;
			pSignedMessageBlob->pbData = pbSignedMessageBlob;
			//DWORD cbEncodedBlob = SignedMessage.cbData;
		}
	}
	else
	{
		MyHandleError(TEXT("Error getting signed BLOB"));
		exit_SignMessage(pbSignedMessageBlob); 
		return fReturn;
	}

	//AfxMessageBox("Подпись готова");

	return fReturn;
}


Спасибо!

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

Offline Новожилова Елена  
#4 Оставлено : 16 января 2012 г. 19:52:48(UTC)
Новожилова Елена

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

Группы: Администраторы, Участники
Зарегистрирован: 10.12.2008(UTC)
Сообщений: 924
Женщина
Откуда: Крипто-Про

Поблагодарили: 99 раз в 95 постах
Здравствуйте!

Вы можете воспользоваться функцией CryptMsgControl с параметром CMSG_CTRL_ADD_SIGNER.

Алгоритм примерно такой:
CryptMsgOpenToDecode()
CryptMsgUpdate()
CryptMsgControl(CMSG_CTRL_ADD_SIGNER) - чтобы добавить "параллельную" подпись
CryptMsgGetParam(CMSG_ENCODED_MESSAGE) - чтобы получить подписанное сообщение.
CryptMsgClose()

А что мешает вам использовать функцию CryptSignMessage для создания и отделенной подписи и присоединенной? С использованием параметра fDetachedSignature.
Offline andreyxvo  
#5 Оставлено : 18 января 2012 г. 15:12:30(UTC)
andreyxvo

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

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

Спасибо большое! Подсказки очень помогли сдвинуться с "мертвой" точки.

Нашел пример создания параллельной подписи, с его помощью почти все получилось. НО возник вопрос:"Параллельную подпись можно создать только для присоединенной подписи? А если нет, то как это осуществить?"
Online Андрей Писарев  
#6 Оставлено : 18 января 2012 г. 15:15:47(UTC)
Андрей *

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

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

Сказал «Спасибо»: 550 раз
Поблагодарили: 2212 раз в 1727 постах
andreyxvo написал:
Спасибо большое! Подсказки очень помогли сдвинуться с "мертвой" точки.

Нашел пример создания параллельной подписи, с его помощью почти все получилось. НО возник вопрос:"Параллельную подпись можно создать только для присоединенной подписи? А если нет, то как это осуществить?"


для отсоединенной - сначала ее считать, CryptMsgUpdate ...
далее по аналогии ..
Техническую поддержку оказываем тут
Наша база знаний
Offline andreyxvo  
#7 Оставлено : 18 января 2012 г. 17:52:51(UTC)
andreyxvo

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

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

Понял, что ни чего не понял....
Здесь нешел общий алгоритм использования CryptMsgUpdate

Цитата:

1) CryptMsgOpenToDecode(..., CMSG_DETACHED_FLAG, ... )
2) CryptMsgUpdate( ..., TRUE) - загрузка значения подписи
3) CryptMsgUpdate( ..., FALSE) ... CryptMsgUpdate( ..., TRUE) - зарузка значений данных, на которых подпись будут проверять
....


Я написал такую абра-кадабру:
Код:


 // Было при проверке присоединенной подписи. Добавил только флаг CMSG_DETACHED_FLAG
    // Open a message for decoding.
    if(!(hMsg = CryptMsgOpenToDecode(
        MY_ENCODING_TYPE,
        CMSG_DETACHED_FLAG,
        0,
        NULL,
        NULL,
        NULL)))
    {
        MyHandleError(TEXT("CryptMsgOpenToDecode failed."));
        goto exit_CosignMessage;
    }


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

// Теперь вроде как надо считать открытые данные...
// Беру еще раз CryptMsgUpdate()	
// LPSTR = "Hello World";	 
	
    if(!(CryptMsgUpdate(
        hMsg,
        (BYTE*)sMsg,
        strlen(sMsg),
        TRUE)))
    {
        MyHandleError(TEXT("CryptMsgUpdate failed."));
        goto exit_CosignMessage;
    }



Что-то я здесь не правильно сделал... Как правильно? Может где какой флаг прошляпил...
Online Андрей Писарев  
#8 Оставлено : 18 января 2012 г. 18:04:56(UTC)
Андрей *

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

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

Сказал «Спасибо»: 550 раз
Поблагодарили: 2212 раз в 1727 постах
исходная ЭЦП - присоединенная?
а в тексте - CryptMsgOpenToDecode ( .. CMSG_DETACHED_FLAG ..)
Техническую поддержку оказываем тут
Наша база знаний
Offline andreyxvo  
#9 Оставлено : 18 января 2012 г. 18:09:48(UTC)
andreyxvo

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

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

Да. Подпись нужна отсоединенная. С присоединенной все работает.
надо?

или сначала CryptMsgOpenToDecode ( .. CMSG_DETACHED_FLAG ..) а потом CryptMsgOpenToEncode ( .. CMSG_DETACHED_FLAG ..)?

В pSignedMessageBlob живет готовая отсоединенная подпись.

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

Offline Павел Смирнов  
#10 Оставлено : 27 января 2012 г. 21:09:03(UTC)
Павел Смирнов

Статус: Вам и не снилось

Группы: Администраторы
Зарегистрирован: 24.12.2007(UTC)
Сообщений: 831
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 48 раз в 44 постах
Вопросы добавления параллельной подписи в сообщение CMS с помощью CryptoAPI лучше обсудить в ветке Встраивание.
Техническую поддержку оказываем тут.
Наша база знаний.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
2 Страницы12>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.