Correctly get sha-1 for files using openssl

I am trying to get sha-1 for multiple files. What I am doing now is a cycle of files in a given path, open and read each file separately and load the contents into the buffer, and then send it to the openssl SHA functions to receive the hash. The code looks something like this:

    void ReadHashFile(LPCTSTR name)
{
 FILE * pFile;
 long lSize;
 char * buffer;
 size_t result;

 pFile = _tfopen ( name , L"rb" );
 if (pFile==NULL) {fputs ("File error",stderr); return;}

 // obtain file size:
 fseek (pFile , 0 , SEEK_END);
 lSize = ftell (pFile);
 rewind (pFile);

 if(lSize == -1){fputs ("Read Error",stderr);return;}

 // allocate memory to contain the whole file:
 buffer = (char*) malloc (sizeof(char)*lSize);
 if (buffer == NULL) {fputs ("Memory error",stderr); return;}

 // copy the file into the buffer:
 result = fread (buffer,1,lSize,pFile);
 if (result != lSize) {fputs ("Reading error",stderr); return;}

 /* the whole file is now loaded in the memory buffer. */

 // terminate
 fclose (pFile);

 //Do what ever with buffer
 unsigned char ibuf[] = "compute sha1";
 unsigned char obuf[20];

 SHA1((const unsigned char*)buffer, strlen((const char*)buffer), obuf);
 fwprintf(stderr, L"file %s\n", name);
 int i;
 for (i = 0; i < 20; i++) {
  printf("%02x ", obuf[i]);
 }
 printf("\n");


 free(buffer);
}

Some files seem unreadable, some of them give me the size of the 1st size, I can only read the first 2-3 bytes, which gives a lot of files of the same step, even if they are different.

I would appreciate if someone could help me with this, or if anyone has experience in hashing files. Oh, and is there a way to get the sha1 file without first loading the entire file in memory, I mean looking at large files, this solution will not work.

Hi

+3
1

, , .

fopen(), _tfopen(). C , . , _tfopen(), , fopen(), Windows _wfopen() , "unicode". , Windows- Win32, CreateFile().

, - . , , , . , , , ( , , ). - ; (8 kB - ) SHA1_Init(), SHA1_Update() SHA1_Final().

fread() , . .

SHA1(), strlen() , . strlen() ; , . 0. , , 0, strlen() ( ). , , , .

: (untested):

/*
 * Hash a file, which name is given. Hash output is written out in
 * buffer "out[]". The hash output consists in exactly 20 bytes.
 * On success, 0 is returned; on error, returned value is -1 and
 * out[] is unaltered.
 */
int
do_sha1_file(char *name, unsigned char *out)
{
    FILE *f;
    unsigned char buf[8192];
    SHA_CTX sc;
    int err;

    f = fopen(name, "rb");
    if (f == NULL) {
        /* do something smart here: the file could not be opened */
        return -1;
    }
    SHA1_Init(&sc);
    for (;;) {
        size_t len;

        len = fread(buf, 1, sizeof buf, f);
        if (len == 0)
            break;
        SHA1_Update(&sc, buf, len);
    }
    err = ferror(f);
    fclose(f);
    if (err) {
        /* some I/O error was encountered; report the error */
        return -1;
    }
    SHA1_Final(out, &sc);
    return 0;
}

! (<stdio.h> sha.h OpenSSL)

+14

Source: https://habr.com/ru/post/1759301/


All Articles