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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Серёня  
#1 Оставлено : 29 июля 2016 г. 16:04:57(UTC)
Серёня

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

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

Сказал «Спасибо»: 2 раз
Добрый день.

У нас реализована расшифровка файлов через функцию CryptDecryptMessage. Все было хорошо, пока на некоторых файлах не начала появляться ошибка 0x80093106 CRYPT_E_ASN1_MEMORY. Похоже, что это происходит со всеми файлами размером от 3Mb. Проблема встречается на машине в рабочей системе, однако на машине разработчиков нормально расшифровываются файлы до 50Mb.

Вопрос, как решить данную проблему? Необходимо шифровать и расшифровывать файлы в формате PKSC#7. Видели, что есть возможность выполнять данные операции поблочно, но как потом получить сообщение в формате PKCS#7?

Версия КриптоПро CSP 3.6.6497.

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

Offline Максим Коллегин  
#2 Оставлено : 29 июля 2016 г. 16:29:05(UTC)
Максим Коллегин

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

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

Сказал «Спасибо»: 37 раз
Поблагодарили: 719 раз в 623 постах
Нужно использовать поточный режим cryptmsgopentoencode/cryptmsgupdate.
Знания в базе знаний, поддержка в техподдержке
Offline Серёня  
#3 Оставлено : 4 августа 2016 г. 16:45:01(UTC)
Серёня

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

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

Сказал «Спасибо»: 2 раз
С этим вопросом разобрались, спасибо.

Возникла еще одна проблема. Расшифровка некоторых файлов падает на функции CryptMsgControl с ошибкой 0x00000057 неверный параметр.
Как и чем шифруются эти файлы - не известно. При внимательном их рассмотрении было выявлено, что в них используется узел замены OID 1.2.643.7.1.2.5.1.1, в то время как по умолчанию используется OID 1.2.643.2.2.31.1. Версия КриптоПро CSP 3.6.6497.

Как решить эту проблему? Обновление CSP поможет? Есть еще варианты? Спасибо.
Offline Максим Коллегин  
#4 Оставлено : 4 августа 2016 г. 18:29:22(UTC)
Максим Коллегин

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

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

Сказал «Спасибо»: 37 раз
Поблагодарили: 719 раз в 623 постах
Да, это новый узел замены. Обновление до CSP 4.0 поможет.
Знания в базе знаний, поддержка в техподдержке
Offline Серёня  
#5 Оставлено : 5 августа 2016 г. 17:16:48(UTC)
Серёня

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

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

Сказал «Спасибо»: 2 раз
Ясно, спасибо.

А поясните, пожалуйста, как работает КриптоАрм?
На машине с CSP 3.6 КриптоАрм эти файлы расшифровывает успешно. КрипотАрм использует свой CSP или как?
Offline Максим Коллегин  
#6 Оставлено : 5 августа 2016 г. 19:34:03(UTC)
Максим Коллегин

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

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

Сказал «Спасибо»: 37 раз
Поблагодарили: 719 раз в 623 постах
А версия CSP какая? Попробуйте 3.6.7777 - в нём уже есть поддержка этого узла.

Отредактировано пользователем 5 августа 2016 г. 19:36:27(UTC)  | Причина: Не указана

Знания в базе знаний, поддержка в техподдержке
Offline Серёня  
#7 Оставлено : 15 августа 2016 г. 11:41:44(UTC)
Серёня

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

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

Сказал «Спасибо»: 2 раз
Спасибо, с версией 3.6.7777 все нормально расшифровывается.

Но у нас снова возникла проблема))

Переводим функцию шифрования на поточный вариант. Все вроде бы работает, но то что получается не удается расшифровать ни через КриптоАрм, ни нашим кодом. Сообщения зашифрованные через CryptEncryptMessage расшифровываются нормально.

Итак, вот код шифрования (наброски)

Код:
int __stdcall encodeCallback(const void* pvArg, byte_t *data, uint_t datalength, int fFinal)
{
	std::vector<byte_t>* container = reinterpret_cast<std::vector<byte_t>*>(const_cast<void*>(pvArg));

	if (container == 0) {
		LOG << ELogLevel::Error << L"encodeCallback function error: container pointer == 0\n" << ELog::Flush;
		return FALSE;
	}

	for (uint_t i = 0; i < datalength; i++)
		container->push_back(data[i]);

    return TRUE;
}

uint_t beginEncryption_GOST(byte_t* recipientCertBlob, uint_t recipientCertBlobLength)
{
	LOG << ELogLevel::Info << L"-------Begin encryption-------\n" << ELog::Flush;

	// Получение дескриптора криптографического провайдера.
    if(!CryptAcquireContext(
			&g_hCryptProv,			// Адрес возврашаемого дескриптора.
			0,						// Используется имя текущего зарегестрированного пользователя.
			NULL,					// Используется провайдер по умолчанию.
			PROV_GOST_2001_DH,		// Необходимо для зашифрования и подписи.
			CRYPT_VERIFYCONTEXT))	// Никакие флаги не нужны.
    {
		uint_t err = GetLastError();
		LOG << ELogLevel::Error << L"Error number     : " << err << "\n";
		LOG << ELog::Tab << L"Error during CryptAcquireContext.\n" << ELog::Flush;
		if(!err)
			err = INTERNAL_FUNCTION_ERROR;
		return err;
    }

	LOG << ELogLevel::Info << L"CSP has been acquired.\n" << ELog::Flush;

	if (g_pCertRecipient)
		CertFreeCertificateContext(g_pCertRecipient);

	g_pCertRecipient = getCertContextFromBlob(recipientCertBlob, recipientCertBlobLength);

	if (!g_pCertRecipient) {
		LOG << ELogLevel::Error << L"Can't acquire recipient certificate contex.\n" << ELog::Flush;
		CryptReleaseContext(g_hCryptProv, 0);
		g_hCryptProv = 0;
		uint_t err = GetLastError();
		if(!err)
			err = INTERNAL_FUNCTION_ERROR;
		return err;
	}

	LOG << ELogLevel::Info << "A recipient's certificate has been acquired.\n" << ELog::Flush;

	g_recipientsCertInfoArray[0] = g_pCertRecipient->pCertInfo;

	memset(&g_encryptAlgorithm, 0, sizeof(CRYPT_ALGORITHM_IDENTIFIER));
	g_encryptAlgorithm.pszObjId = szOID_CP_GOST_28147;

	memset(&g_envelopedEncodeInfo, 0, sizeof(CMSG_ENVELOPED_ENCODE_INFO));
	g_envelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
	g_envelopedEncodeInfo.hCryptProv = g_hCryptProv;
	g_envelopedEncodeInfo.ContentEncryptionAlgorithm = g_encryptAlgorithm;
	g_envelopedEncodeInfo.cRecipients = 1;
	g_envelopedEncodeInfo.rgpRecipients = g_recipientsCertInfoArray;
	g_envelopedEncodeInfo.pvEncryptionAuxInfo = 0;

	return 0;
}

uint_t doEncrypt_GOST(byte_t* data, uint_t dataLength, byte_t*& encryptedData, uint_t& encryptedDataLength)
{
	LOG << ELogLevel::Info << L"-------Encryption (stream)-------\n" << ELog::Flush;
	
	std::vector<byte_t> dataContainer;

	// Fill the CMSG_STREAM_INFO structure.
    CMSG_STREAM_INFO MsgStreamInfo;

    //MsgStreamInfo.cbContent = CMSG_INDEFINITE_LENGTH; // BER_ENCODING
	MsgStreamInfo.cbContent = dataLength; // DER_ENCODING
    MsgStreamInfo.pfnStreamOutput = encodeCallback;
	MsgStreamInfo.pvArg = &dataContainer;

	HCRYPTMSG hMsg = 0;

	// Откроем сообщение для кодирования
	hMsg = CryptMsgOpenToEncode(
				ENCODING_TYPE,          /* Encoding type*/
				0,                      /* Flags*/
				CMSG_ENVELOPED,         /* Message type*/
				&g_envelopedEncodeInfo, /* Pointer to structure*/
				NULL,                   /* Inner content object ID*/
				&MsgStreamInfo);        /* Stream information*/

	if (!hMsg) {
		uint_t err = GetLastError();
		LOG << ELogLevel::Error << L"Error number     : " << err << "\n";
		LOG << ELog::Tab << L"CryptMsgOpenToEncode failed.\n" << ELog::Flush;

		if(!err)
			err = INTERNAL_FUNCTION_ERROR;
		return err;
	}

	LOG << ELogLevel::Info << L"The message to decode is open.\n" << ELog::Flush;

	uint_t blocksCount = dataLength / STREAM_BLOCK_SIZE_BYTES;
	uint_t lastBlockSize = dataLength % STREAM_BLOCK_SIZE_BYTES;

	LOG << ELogLevel::Info << L"STREAM_BLOCK_SIZE_BYTES: " << static_cast<int>(STREAM_BLOCK_SIZE_BYTES) << L"\n" << ELog::Flush;
	LOG << ELogLevel::Info << L"blocksCount: " << static_cast<int>(blocksCount) << L"\n" << ELog::Flush;
	LOG << ELogLevel::Info << L"lastBlockSize: " << static_cast<int>(lastBlockSize) << L"\n" << ELog::Flush;

	uint_t result = 0;

	for (uint_t i = 0; i < blocksCount; i++) {
		int bLast = TRUE;
		if (lastBlockSize || (!lastBlockSize && i < blocksCount - 1)) {
			bLast = FALSE;
		}

		if(!CryptMsgUpdate(
			hMsg,                                 // handle to the message
			data + (i * STREAM_BLOCK_SIZE_BYTES), // pointer to the encoded BLOB
			STREAM_BLOCK_SIZE_BYTES,              // size of the encoded BLOB
			bLast))                               // last call
		{
			result = GetLastError();
			LOG << ELogLevel::Error << result << "\n";
			LOG << ELog::Tab << L"CryptMsgUpdate failed.\n" << ELog::Flush;

			if(!result)
				result = INTERNAL_FUNCTION_ERROR;
			break;
		}
	}

	if (0 == result)
		LOG << ELogLevel::Info << L"Loop CryptMsgUpdate finishesd successfully.\n" << ELog::Flush;

	if (lastBlockSize && 0 == result) {
		if(!CryptMsgUpdate(
			hMsg,                                                    // handle to the message
			data + (blocksCount * STREAM_BLOCK_SIZE_BYTES), // pointer to the encoded BLOB
			lastBlockSize,                                           // size of the encoded BLOB
			TRUE))                                                   // last call
		{
			result = GetLastError();
			LOG << ELogLevel::Error << result << "\n";
			LOG << ELog::Tab << L"CryptMsgUpdate failed (last).\n" << ELog::Flush;

			if(!result)
				result = INTERNAL_FUNCTION_ERROR;
		} else {
			LOG << ELogLevel::Info << L"Last CryptMsgUpdate finishesd successfully.\n" << ELog::Flush;
		}
	}

	CryptMsgClose(hMsg);

	if (result == 0) {
		// Save data
		encryptedDataLength = dataContainer.size();
		encryptedData = new byte_t[encryptedDataLength];
		memcpy(encryptedData, dataContainer.data(), encryptedDataLength);

		ResourceCleaner::addForLaterClean(encryptedData);
	}

	return result;
}

uint_t endEncryption_GOST()
{
	if (g_pCertRecipient) {
		CertFreeCertificateContext(g_pCertRecipient);
		g_pCertRecipient = 0;
	}

	if (g_hCryptProv) {
		CryptReleaseContext(g_hCryptProv, 0);
		g_hCryptProv = 0;
	}

	g_recipientsCertInfoArray[0] = 0;

	return 0;
}


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


Код:
2016-08-15 11:30:59     Info: -------Begin decryption-------
2016-08-15 11:30:59     Info: -------Get provider for user-------
2016-08-15 11:30:59     Info: -------findProvForUserContainer-------
2016-08-15 11:30:59     Info: Certificate context successfully created.
2016-08-15 11:30:59     Info: AcquireContext OK.
2016-08-15 11:30:59     Info: Container name: reg1
2016-08-15 11:30:59     Info: Container found.
2016-08-15 11:30:59     Info: Trying to get AT_KEYEXCHANGE key from container.
2016-08-15 11:30:59     Info: The AT_KEYEXCHANGE key has been acquired.
2016-08-15 11:30:59     Info: Cert blob length has been acquired.
2016-08-15 11:30:59     Info: Cert blob has been acquired.
2016-08-15 11:30:59     Info: Certificate context successfully created.
2016-08-15 11:30:59     Info: -----Compare certificates!-----
2016-08-15 11:30:59     Info: Compare success!
2016-08-15 11:30:59     Info: Password for container has been set.
2016-08-15 11:30:59     Info: CSP has been acquired.
Open file in binary mode: D:\Projects\DigitalSignature\DebugV2\dir1\1.jpg.enc

All bytes read successfully.

2016-08-15 11:30:59     Info: -------Decryption (stream)-------
2016-08-15 11:30:59     Info: The message to decode is open.
2016-08-15 11:30:59     Info: STREAM_BLOCK_SIZE_BYTES: 131072
2016-08-15 11:30:59     Info: blocksCount: 1
2016-08-15 11:30:59     Info: lastBlockSize: 75516
2016-08-15 11:30:59     Info: Got CMSG_ENVELOPE_ALGORITHM_PARAM parametr.
2016-08-15 11:30:59     Info: Got recipient CERT_INFO parametr.
2016-08-15 11:30:59     Info: Cert compare success! Decrypting.
2016-08-15 11:31:00     Error: 0x0000007f
                CryptMsgControl failed.
Open file in binary mode: D:\Projects\DigitalSignature\DebugV2\dir1\2.jpg.enc

All bytes read successfully.

2016-08-15 11:31:00     Info: -------Decryption (stream)-------
2016-08-15 11:31:00     Info: The message to decode is open.
2016-08-15 11:31:00     Info: STREAM_BLOCK_SIZE_BYTES: 131072
2016-08-15 11:31:00     Info: blocksCount: 2
2016-08-15 11:31:00     Info: lastBlockSize: 114199
2016-08-15 11:31:00     Info: Got CMSG_ENVELOPE_ALGORITHM_PARAM parametr.
2016-08-15 11:31:00     Info: Got recipient CERT_INFO parametr.
2016-08-15 11:31:00     Info: Cert compare success! Decrypting.
2016-08-15 11:31:00     Error: 0x00000002
                CryptMsgControl failed.
Open file in binary mode: D:\Projects\DigitalSignature\DebugV2\dir1\D1027739007768.xml.enc

All bytes read successfully.

2016-08-15 11:31:00     Info: -------Decryption (stream)-------
2016-08-15 11:31:00     Info: The message to decode is open.
2016-08-15 11:31:00     Info: STREAM_BLOCK_SIZE_BYTES: 131072
2016-08-15 11:31:00     Info: blocksCount: 0
2016-08-15 11:31:00     Info: lastBlockSize: 1253
2016-08-15 11:31:00     Info: Loop CryptMsgUpdate finishesd successfully.
2016-08-15 11:31:00     Error: 0x80091011
                CryptMsgUpdate failed (last).
Open file in binary mode: D:\Projects\DigitalSignature\DebugV2\dir1\mx_.exe.enc

All bytes read successfully.

2016-08-15 11:31:00     Info: -------Decryption (stream)-------
2016-08-15 11:31:00     Info: The message to decode is open.
2016-08-15 11:31:00     Info: STREAM_BLOCK_SIZE_BYTES: 131072
2016-08-15 11:31:00     Info: blocksCount: 313
2016-08-15 11:31:00     Info: lastBlockSize: 48665
2016-08-15 11:31:00     Info: Got CMSG_ENVELOPE_ALGORITHM_PARAM parametr.
2016-08-15 11:31:00     Info: Got recipient CERT_INFO parametr.
2016-08-15 11:31:00     Info: Cert compare success! Decrypting.
2016-08-15 11:31:00     Error: 0x00000002
                CryptMsgControl failed.

Press Enter to continue:


CryptMsgControl выдает непонятные ошибки 0x00000002, 0x80091011 и 0x0000007f

Код шифрования могу предоставить, если нужно.
Но проблема не в нем похоже, что то не так с шифрованием.

Отредактировано пользователем 15 августа 2016 г. 11:42:48(UTC)  | Причина: Не указана

Offline Серёня  
#8 Оставлено : 15 августа 2016 г. 12:31:02(UTC)
Серёня

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

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

Сказал «Спасибо»: 2 раз
Проблема решилась вот этим

MsgStreamInfo.cbContent = CMSG_INDEFINITE_LENGTH;

Это связано с ошибками в CSP? Чем это грозит?
Offline Максим Коллегин  
#9 Оставлено : 15 августа 2016 г. 13:50:58(UTC)
Максим Коллегин

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

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

Сказал «Спасибо»: 37 раз
Поблагодарили: 719 раз в 623 постах
Старые версии CSP (до 4.0) умеют работать только с -1.
Знания в базе знаний, поддержка в техподдержке
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.