Obliczanie i drukowanie pliku skrótu SHA256 przy użyciu OpenSSL


Próbuję napisać funkcję C przy użyciu OpenSSL/libcrypto do obliczenia sumy SHA256 pliku. Mój kod opieram na przykładzie C ++ Adama Lamera

tutaj
http://adamlamers.com/?p=5
.
Oto mój kod:
int main (int argc, char** argv)
{
char calc_hash[65]; calc_sha256("file.txt", calc_hash);
}int calc_sha256 (char* path, char output[65])
{
FILE* file = fopen(path, "rb");
if(!file) return -1; char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
const int bufSize = 32768;
char* buffer = malloc(bufSize);
int bytesRead = 0;
if(!buffer) return -1;
while((bytesRead = fread(buffer, 1, bufSize, file)))
{
SHA256_Update(&sha256, buffer, bytesRead);
}
SHA256_Final(hash, &sha256); sha256_hash_string(hash, output);
fclose(file);
free(buffer);
return 0;
} void sha256_hash_string (char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65])
{
int i = 0; for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
sprintf(outputBuffer + (i * 2), "x", hash[i]);
} outputBuffer[64] = 0;
}

Problem polega na tym ... spójrz na obliczone sumy poniżej dla przykładowego pliku:
Known good SHA256: 6da032d0f859191f3ec46a89860694c61e65460d54f2f6760b033fa416b73866
Calc. by my code: 6dff32ffff59191f3eff6affff06ffff1e65460d54ffff760b033fff16ff3866

Po zakończeniu wykonywania kodu otrzymuję również * wykrycie rozbicia stosu *.
Czy ktoś widzi, co robię źle?
Podziękować!
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wygląda na to, że w Twoim wyjściu znajduje się wiele bloków „0xff”, a odpowiadające im bloki w dobrym łańcuchu mają wysoki bit ... może jest gdzieś problem z rozszerzaniem znaku.
Bez robienia:
char hash[SHA256_DIGEST_LENGTH];

bez podpisu, na przykład:
unsigned char hash[SHA256_DIGEST_LENGTH];

Wsparcie? (Szczególnie w podpisie
sha256_hash_string
.)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ty drukujesz

znak
char
jako liczba całkowita. Jeśli bajt jest ujemny, jest konwertowany na
signed int
(

domyślny argument

używany w wywołaniu
sprintf
), a następnie konwertowany na
unsigned int
(za pomocą specyfikatora formatu
% x
) i drukowany.
Zatem bajt
A0
to -96 jako bajt ze znakiem, który jest konwertowany na -96 jako
signed int
, czyli 0xFFFFFFA0 w zapisie szesnastkowym, więc jest drukowany jako FFFFFFA0.
Aby to naprawić, każdy bajt powinien zostać zapisany w
unsigned char
przed wydrukowaniem:
sprintf(..., (unsigned char)hash[i]);

Otrzymujesz ostrzeżenie o podziale stosu, ponieważ na końcu skrótu znajduje się podpisany bajt, więc piszesz 8 bajtów FFFFFFB7 z przesunięciem 58, gdy zamierzałeś zapisać tylko 2 bajty. To prowadzi do
Przepełnienie bufora
http://en.wikipedia.org/wiki/Buffer_overflowco pojawia się tutaj, ponieważ kompilator najprawdopodobniej umieścił obszar ochrony lub plik cookie bezpieczeństwa na stosie przed wartością zwracaną i stwierdził, że obszar ochrony został przypadkowo zmieniony.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się