Статус: Участник
Группы: Участники
Зарегистрирован: 03.03.2014(UTC) Сообщений: 22 ![Мужчина Мужчина](/forum2/Themes/soclean/male.gif) ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Москва Сказал «Спасибо»: 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)
| Причина: Не указана
|