Я пытаюсь написать программу на C++ для шифрования и дешифрования определенных файлов. Шифрование работает отлично, но когда я прихожу для дешифрования функции, похоже, вызывает сбои в программе.Расшифровать AES-зашифрованный файл, вызвав ошибку
Вот функция, я использую для дешифрования:
CString DecryptFile(CString csSourceFile)
{
CString csDecryptedFile = csSourceFile;
CRijndael aesEncryption;
int nPos = csDecryptedFile.ReverseFind('.');
if(nPos == -1)
{
//Log("ERROR:: file name not proper");
return CString("");
}
csDecryptedFile = csDecryptedFile.Left(nPos);
csDecryptedFile += ".wav";
FILE *fIn = fopen(csSourceFile.GetBuffer(0),"rb");
FILE *fOut = fopen(csDecryptedFile.GetBuffer(0),"wb");
if(!fIn || !fOut)
{
//Log("ERROR:: failed to Open File for encryption");
return CString("");
}
int nlen = -1;
aesEncryption.MakeKey(AM_ENC_KEY,AM_NULL_KEY,BLOCK_SIZE,BLOCK_SIZE);
int nRead = 0;
while (true) {
char szBlockIn[EBLOCK_SIZE+1] = {0};
char szBlockOut[BLOCK_SIZE+1] = {0};
char szBlockDec[BLOCK_SIZE+1] = {0};
memset(szBlockIn,0,sizeof(char)*(EBLOCK_SIZE+1));
memset(szBlockOut,0,sizeof(char)*(BLOCK_SIZE+1));
memset(szBlockDec,0,sizeof(char)*(BLOCK_SIZE+1));
int nRead = fread(szBlockIn,sizeof(char),EBLOCK_SIZE, fIn);
if(nRead <= 0) {
break;
}
nlen = EBLOCK_SIZE;
Decode(szBlockIn,szBlockOut,nlen);
aesEncryption.DecryptBlock((char *)szBlockOut,szBlockDec);
fwrite(szBlockDec,sizeof(char),BLOCK_SIZE,fOut);
}
fclose(fIn);
fclose(fOut);
RemoveEndTag(csDecryptedFile.GetBuffer(0));
AfxMessageBox(csDecryptedFile);
AfxMessageBox(_T("returning"));
return csDecryptedFile;
}
Это фрагмент кода, который вызывает функцию:
CString strTest = DecryptFile(m_DecompressedTempFile);
AfxMessageBox(strTest);
Что такое странное, что дешифрование выполняется прекрасно - если я попаду в папку с файлом, я могу увидеть расшифрованный файл и получить доступ к нему. К сожалению, программа должна делать больше, чем это, и программа просто висит сразу же после. Особенно странно то, что, как вы видите, я звоню AfxMessageBox(_T("returning"));
до конца функции: это создает сообщение в порядке. Но когда я вызываю AfxMessageBox(strTest);
из кода, который запускает эту функцию, окно сообщения не создается.
С помощью отладки кажется, что проблема каким-то образом маршрутизируется во время цикла, который у меня есть для шифрования файла, поэтому мне интересно, не закрываю ли я что-то, что я должен или что-то еще? Не совсем уверен, что делать с этим, так что любой, кто может предложить любую помощь, будет отличным!?!
Заранее спасибо.
Я забыл упомянуть, что это работало много лет назад - единственное недавнее изменение заключается в том, что мы сейчас компилируем код в Windows 7, а ранее это Windows XP. Будет ли это иметь значение для чего-либо в функции?
Обновление: Следует отметить, что если я удаляю цикл while и запускаю содержимое цикла только один раз, возникает та же проблема. Если я удалю aesEncryption.DecryptBlock((char *)szBlockOut,szBlockDec);
, проблема исчезнет, но, очевидно, мне нужна эта строка. Поэтому проблема направлена на эту функцию, я думаю. Хотя эта функция существует в библиотеке, я hvae включил его ниже:
//Decrypt exactly one block of ciphertext.
// in - The ciphertext.
// result - The plaintext generated from a ciphertext using the session key.
void CRijndael::DecryptBlock(char const* in, char* result)
{
if(false==m_bKeyInit)
throw exception(sm_szErrorMsg1);
if(DEFAULT_BLOCK_SIZE == m_blockSize)
{
DefDecryptBlock(in, result);
return;
}
int BC = m_blockSize/4;
int SC = BC == 4 ? 0 : (BC == 6 ? 1 : 2);
int s1 = sm_shifts[SC][1][1];
int s2 = sm_shifts[SC][2][1];
int s3 = sm_shifts[SC][3][1];
//Temporary Work Arrays
int i;
int tt;
int* pi = t;
for(i=0; i<BC; i++)
{
*pi = ((unsigned char)*(in++) << 24);
*pi |= ((unsigned char)*(in++) << 16);
*pi |= ((unsigned char)*(in++) << 8);
(*(pi++) |= (unsigned char)*(in++)) ^= m_Kd[0][i];
}
//Apply Round Transforms
for(int r=1; r<m_iROUNDS; r++)
{
for(i=0; i<BC; i++)
a[i] = (sm_T5[(t[i] >> 24) & 0xFF]^
sm_T6[(t[(i + s1) % BC] >> 16) & 0xFF]^
sm_T7[(t[(i + s2) % BC] >> 8) & 0xFF]^
sm_T8[ t[(i + s3) % BC] & 0xFF])^m_Kd[r][i];
memcpy(t, a, 4*BC);
}
int j;
//Last Round is Special
for(i=0,j=0; i<BC; i++)
{
tt = m_Kd[m_iROUNDS][i];
result[j++] = sm_Si[(t[i] >> 24) & 0xFF]^(tt >> 24);
result[j++] = sm_Si[(t[(i + s1) % BC] >> 16) & 0xFF]^(tt >> 16);
result[j++] = sm_Si[(t[(i + s2) % BC] >> 8) & 0xFF]^(tt >> 8);
result[j++] = sm_Si[ t[(i + s3) % BC] & 0xFF]^tt;
}
}
Является ли это, что 'GetBuffer (0) 'call? http://msdn.microsoft.com/en-us/library/aa314880%28v=vs.60%29.aspx Поскольку CString является ссылочной подсчитанной строкой, вам может потребоваться вызвать 'ReleaseBuffer' – PaulMcKenzie
Спасибо за это, ReleaseBuffer должно быть обязательно там. К сожалению, это не помогло проблемы с подвеской :( – Raiden616
Возможно, вам стоит использовать другую библиотеку AES, поскольку тот, который вы используете, похоже, не попал под многоуровневый обзор: http://www.codeproject.com/Articles/1380/AC-Implementation-of-the-the-Rijndael-Encryption-Decr – PaulMcKenzie