Sto tentando di crittografare un messaggio di testo con wincrypt. Il mio codice è comunque imprevedibile. Non crittografa / decodifica l’intero testo in chiaro ma solo una parte di esso. Se cambio la lunghezza della password (ad esempio in “password123”) codifica / decodifica una diversa quantità di caratteri. Ecco il mio codice.
#include #include #include int main() { const char* passw = "password12"; const char* toencrypt = "consectetur adipiscing elit. In tellus nisl, sodales non arcu quis, sagittis maximus orci cras amet."; HCRYPTPROV hProv; HCRYPTHASH hHash; HCRYPTKEY hKey; DWORD todwSize = (DWORD)strlen(toencrypt); PBYTE pBuffer; CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET); CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash); CryptHashData(hHash, (BYTE*)passw, strlen(passw), 0); CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey); //-------------------------------------------------------------------- CryptEncrypt(hKey, 0, TRUE, 0, NULL, &todwSize, todwSize); pBuffer = (BYTE *)malloc(todwSize); strcpy((char*)pBuffer, toencrypt); CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, todwSize); PBYTE pBreturn = pBuffer; const char* message = (const char*)pBreturn; printf("%s", message); //-------------------------------------------------------------------- DWORD dwSize = (DWORD)strlen(message); PBYTE depBuffer; depBuffer = (BYTE *)malloc(1460); strcpy((char*)depBuffer, message); CryptDecrypt(hKey, 0, TRUE, 0, depBuffer, &dwSize); CryptDestroyKey(hKey); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); if(GetLastError() != 0) { printf("%d", GetLastError()); } PBYTE depBreturn = depBuffer; printf("%s", (const char*)depBreturn); printf("\n%d", strlen(message)); return 0; }
Grazie in anticipo per l’aiuto!
pensa che il tuo codice sia crittografato ok, ma non riesci a decifrare l’intero messaggio perché usi la lunghezza sbagliata nella chiamata CryptDecrypt
il tuo errore principale è DWORD dwSize = (DWORD)strlen(message);
e strcpy((char*)depBuffer, message);
ma il messaggio è buffer crittografato, non 0 termina stringa ansi. quindi non puoi usare strlen
o strcpy
su dati crittografati – hai la lunghezza dei dati crittografati restituita da CryptEncrypt
: todwSize
– così tu e devi usare con memcpy
se hai bisogno di copiare il buffer crittografato e passare todwSize
come è a CryptDecrypt
anche come ha notato Harry Johnston
che usi scorrettamente la dimensione dei dati / buffer nella chiamata CryptEncrypt
.
deve essere CryptEncrypt(hKey, 0, TRUE, 0, NULL, &(needSize = todwSize), 0)
alla prima chiamata (l’ultimo parametro di CryptEncrypt
dwBufLen deve essere 0 perché si usa NULL come buffer e si deve usare un’altra variabile DWORD needSize
per ottenere la dimensione del buffer crittografato e non sovrascrivere la dimensione del buffer di testo normale ( todwSize
), quindi assegnare il buffer needSize
, copiarlo su todSize
e chiamare CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, needSize)
. ma tuttavia per RC4 il criptato e le dimensioni del testo normale sono sempre uguali, quindi needSize == todSize
sempre nel caso di RC4
inoltre è necessario chiamare CryptAcquireContext
una sola volta con flag CRYPT_VERIFYCONTEXT
nel tuo caso. e ha sempre bisogno di controllare il risultato della funzione. quindi il codice di prova può essere così
int main() { const char* passw = "password12"; const char* toencrypt = "consectetur adipiscing elit. In tellus nisl, sodales non arcu quis, sagittis maximus orci cras amet."; HCRYPTPROV hProv; HCRYPTHASH hHash; HCRYPTKEY hKey; DWORD todwSize = (DWORD)strlen(toencrypt), needSize; PBYTE pBuffer; if (CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { if (CryptHashData(hHash, (BYTE*)passw, (DWORD)strlen(passw), 0) && CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey)) { if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &(needSize = todwSize), 0)) { memcpy(pBuffer = (BYTE *)_alloca(needSize), toencrypt, todwSize); if (CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, needSize)) { if (CryptDecrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize)) { if (memcmp(pBuffer, toencrypt, strlen(toencrypt))) { __debugbreak(); } } } } CryptDestroyKey(hKey); } CryptDestroyHash(hHash); } CryptReleaseContext(hProv, 0); } return 0; }