winapi - CryptDecrypt() Failing to decrypt some blocks C++ -
i'm working on simple encryption/decryption system in c++ using windows api.
i believe i've been successful @ getting cryptencrypt() work (aes_128) encrypting file. when use cryptdecrypt() decrypt file, first 16 bytes corrupted , after 4000 bytes (which size of chunks i'm pulling readfile() , encrypting) chunk of corrupted bytes , on. if try decrypt file total length less 4000 bytes, decryption works perfectly.
i'm confused why happening. there no errors @ all.
here snippet of code (i have cryptencrypt() , cryptdecrypt() right after each other save me exporting key , make testing faster):
dword bytesread; dword byteswritten; dword pointer = 0; unsigned int blocksize = 4000; void *filebuffer = new unsigned char[4106]; bool eof = false; { setfilepointer(hfileorginal,pointer,0,0); readfile(hfileorginal,filebuffer,blocksize,&bytesread,null); if(bytesread<blocksize) { eof=true; } cryptencrypt(aeskey,null,eof,0,(byte *)filebuffer,&bytesread,(blocksize+16)); cryptdecrypt(aeskey,null,eof,0,(byte *)filebuffer,&bytesread); writefile(htempfile,filebuffer,bytesread,&byteswritten,null); pointer +=bytesread; } while(!eof); delete[] filebuffer; i appreciate suggestions whats going wrong.
edit: on 4704 bytes file got following using breakpoints.
first readfile bytesread 4000 first cryptencrypt bytesread 4000 first cryptdecrypt bytesread 4000 second readfile bytesread 704 second cryptencrypt bytesread 720 second cryptdecrupt bytesread 704
everything seems yet still problem.
i'm using enhanced crypto api (with verifycontext) generated single aes key crypt_exportable property
you not doing error handling @ all. of api functions calling have return values , error codes, none of checking.
you not managing bytesread correctly. cryptencrypt() modifies variable pass it, affects call createdecrypt(), modifies it, , affects subsequent calls setfilepointer(), should not calling in loop begin with. not validating have many bytes expecting, or bytesread ends @ original value readfile() returned, may end skipping bytes in source file.
try more instead:
bool readfromfile(handle hfile, void *buffer, dword bufsize, dword *bytesread) { if (bytesread) *bytesread = 0; lpbyte pbuffer = (lpbyte) buffer; dword dwread; while (bufsize > 0) { if (!readfile(hfile, pbuffer, bufsize, &dwread, null)) return false; if (dwread == 0) break; pbuffer += dwread; bufsize -= dwread; if (bytesread) *bytesread += dwread; } return true; } bool writetofile(handle hfile, void *buffer, dword bufsize) { lpbyte pbuffer = (lpbyte) buffer; dword dwwritten; while (bufsize > 0) { if (!writefile(hfile, pbuffer, bufsize, &dwwritten, null)) return false; pbuffer += dwwritten; bufsize -= dwwritten; } return true; } dword bytesread; const uint blocksize = 4000; lpbyte filebuffer = new byte[blocksize+16]; bool eof; if (setfilepointer(hfileorginal, 0, null, file_begin) != 0) { errorcode = getlasterror(); ... } else { { if (!readfromfile(hfileorginal, filebuffer, blocksize, &bytesread)) { errorcode = getlasterror(); ... break; } eof = (bytesread < blocksize); bytesencrypted = bytesread; if (!cryptencrypt(aeskey, null, eof, 0, filebuffer, &bytesencrypted, blocksize+16)) { errorcode = getlasterror(); ... break; } bytesdecrypted = bytesencrypted; if (!cryptdecrypt(aeskey, null, eof, 0, filebuffer, &bytesdecrypted)) { errorcode = getlasterror(); ... break; } if (!writetofile(htempfile, filebuffer, bytesdecrypted)) { errorcode = getlasterror(); ... break; } if (bytesdecrypted != bytesread) { ... break; } } while (!eof); } delete[] filebuffer;
Comments
Post a Comment