2

I want to get hash of a binary file whose name I have. I have tried the following, but then realized that SHA1() is returning hash value for the string ( name of the file). But I want to run it on the file itself. Any pointers on how to do that would be great.

char *fileName = "/bin/ls"
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1((unsigned char *)fileName, strlen(fileName),hash);
Neo
  • 349
  • 5
  • 18

4 Answers4

6

Thanks to everyone's comments I solved the problem. I am posting the code here, so others might find it beneficial.

void getFileHash(char *fileName){

unsigned char result[2*SHA_DIGEST_LENGTH];
unsigned char hash[SHA_DIGEST_LENGTH];
int i;
FILE *f = fopen(fileName,"rb");
SHA_CTX mdContent;
int bytes;
unsigned char data[1024];

if(f == NULL){
    printf("%s couldn't open file\n",fileName);
    exit(1);
}

SHA1_Init(&mdContent);
while((bytes = fread(data, 1, 1024, f)) != 0){

    SHA1_Update(&mdContent, data, bytes);
}

SHA1_Final(hash,&mdContent);

for(i=0;i<SHA_DIGEST_LENGTH;i++){
    printf("%02x",hash[i]);
}
printf("\n");
/** if you want to see the plain text of the hash */
for(i=0; i < SHA_DIGEST_LENGTH;i++){
    sprintf((char *)&(result[i*2]), "%02x",hash[i]);
}

printf("%s\n",result);

fclose(f);
}
Neo
  • 349
  • 5
  • 18
1

I don't know how your SHA1() function works (is it from libssl?), but I assume that by

SHA1((unsigned char *)fileName, strlen(fileName),hash);

you are hashing file name, so /bin/ls string. You need to read file content byte by byte into a buffer and hash it.

Oleksandr Kravchuk
  • 5,963
  • 1
  • 20
  • 31
1

You need to read the file chunk by chunk, and compute the digest chunk by chunk.

Read chunks up to e.g. 2048 bytes with fread. Use SHA1_Init in the beginning, SHA1_Update for each chunk, and SHA1_Final in the end.

You can use plain SHA1 function if you read the entire file in one gulp, but this is not recommended.

Another method is to memory-map the file (see mmap() or whatever the Windows equivalent is) and use plain SHA1. This method is very efficient but less portable than the other one.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

You need just give argument of file context to SHA1(). The variable fileName contains string "/bin/ls" and SHA1() function returns hash of that string. Here is simple example how to read file and get hash

   /* Used variables */
   FILE *fp;
   char string[2048];
   unsigned char hash[SHA_DIGEST_LENGTH];
   int t;

   /* Open file */
   fp=fopen("test","r");
   if (fp == NULL)
   {
      printf("Can not open file\n");
      exit(1);
   }

   /* Read file */
   fread (string,1,sizeof(string),fp);

   /* Get hash of file */
   SHA1((unsigned char *)string, strlen(string),hash);

I hope buffer size of string (2048) will be enough for the file context.

Sun Dro
  • 581
  • 4
  • 9
  • This is totally wrong. You cannot use `fscanf` to read file contents, and %d is inexplicable however you look at it. – n. m. could be an AI Apr 02 '15 at 15:56
  • Okay, this was simple example. I don't even tested the code while posting here but the meaning of my comment is that you must give argument of file context to SHA1 function but not a string of file path. I will edit comment – Sun Dro Apr 02 '15 at 16:08