Я написал программу, которая шифрует/расшифровывает буфер памяти пользовательской длины. Эквитация заканчивается хорошо; но мой код дешифрования дешифрует данные только один раз в любой позиции буфера, которая соответствует записям блока. Расшифровка других блоков заканчивается NTE_BAD_DATA.CryptoAPI RSA: CryptDecrypt расшифровывает только один раз, после этого NTE_BAD_DATA
Есть ли у вас какие-либо соображения, почему это происходит?
Вот мой код шифрования:
void CWinRSA::FinishEncrypt(const char* pcbRawData, const size_t nDataSize, char** ppcbEcrData, size_t& rnEcrSize) const
{
if (m_hProvider == NULL)
{
throw ("Cannot encrypt data with wrong provider!!");
}
if (m_hKey == NULL)
{
throw ("Cannot encrypt data with a wrong key!!");
}
size_t nBlockLength = GetBlockLength();
size_t nPaddingSize = nBlockLength - 11;
size_t nRemain = nDataSize % nBlockLength;
size_t nBlockProcess = (nDataSize/nPaddingSize + (nRemain != 0 ? 1 : 0));
size_t nResultSize = nBlockProcess * nBlockLength;
(*ppcbEcrData) = new char[nResultSize];
DWORD dwBufferLength = nBlockLength;
DWORD dwDataLength;
for (int iBlock = 0; iBlock < nBlockProcess - 1; iBlock++)
{
memcpy((*ppcbEcrData) + (iBlock * nBlockLength),
pcbRawData + (iBlock * nPaddingSize), nPaddingSize);
dwDataLength = nPaddingSize;
if (!CryptEncrypt(m_hKey, NULL, FALSE, 0,
(BYTE*)((*ppcbEcrData) + (iBlock * nBlockLength)),
&dwDataLength, dwBufferLength))
{
throw ("Cannot encrypt data!!");
}
}
memcpy((*ppcbEcrData) + ((nBlockProcess - 1) * nBlockLength),
pcbRawData + ((nBlockProcess - 1) * nPaddingSize), (nRemain ? nRemain : nPaddingSize));
dwDataLength = (nRemain ? nRemain : nPaddingSize);
if (!CryptEncrypt(m_hKey, NULL, TRUE, 0,
(BYTE*)((*ppcbEcrData) + ((nBlockProcess - 1) * nBlockLength)),
&dwDataLength, dwBufferLength))
{
throw ("Cannot encrypt data!!");
}
rnEcrSize = nResultSize;
}
расшифровка:
void CWinRSA::FinishDecrypt(const char* pcbRawData, const size_t nDataSize, char** ppcbDecData, size_t& rnDecSize) const
{
if (m_hProvider == NULL)
{
throw ("Cannot decrypt data with wrong provider!!");
}
if (m_hKey == NULL)
{
throw ("Cannot decrypt data with a wrong key!!");
}
size_t nBlockLength = GetBlockLength();
if ((nDataSize % nBlockLength) != 0)
{
throw ("Cannot decrypt data!! Probably data is corrupted!!");
}
size_t nPaddingSize = nBlockLength - 11;
size_t nBlockProcess = nDataSize/nBlockLength;
size_t nResultSize = nBlockProcess * nPaddingSize;
(*ppcbDecData) = new char[nResultSize];
DWORD dwDataLength;
char* pcbComputeResult = new char[nBlockLength];
for (int iBlock = 0; iBlock < nBlockProcess - 1; iBlock++)
{
memcpy(pcbComputeResult, pcbRawData + (iBlock * nBlockLength), nBlockLength);
if (!CryptDecrypt(m_hKey, NULL, FALSE, 0, (BYTE*)pcbComputeResult, &dwDataLength))
{
throw ("Cannot decrypt data!!");
}
memcpy((*ppcbDecData) + (iBlock * nPaddingSize), pcbComputeResult, nPaddingSize);
}
memcpy(pcbComputeResult, pcbRawData + ((nBlockProcess - 1) * nBlockLength), nBlockLength);
if (!CryptDecrypt(m_hKey, NULL, TRUE, 0, (BYTE*)pcbComputeResult, &dwDataLength))
{
DWORD dwError = GetLastError();
throw ("Cannot decrypt data!!");
}
memcpy((*ppcbDecData) + ((nBlockProcess - 1) * nPaddingSize), pcbComputeResult, nPaddingSize);
rnDecSize = ((nBlockProcess - 1) * nPaddingSize) + dwDataLength;
delete[] pcbComputeResult;
pcbComputeResult = NULL;
}
В строке принципе _can_ быть использован в качестве блочного шифра, но это ни предполагаемое использование, ни последствия для безопасности выполнения так были изучены. –