Hello.
I'm using Debian Buster and I want trying to hash a string in a small C program.
What means can I use to accomplish this?
Thanks
Psy
neuraleskimo wrote:Try libmhash, OpenSSL, or GNUTLS. Although you didn't ask for C++, I would steer a beginner to Qt's QCryptographicHash. Good luck!
#include <stdio.h>
#include <openssl/sha.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER 256
int main(void){
const unsigned char* data_to_hash = NULL;
char* hash = NULL;
data_to_hash = calloc(SHA256_DIGEST_LENGTH, sizeof(const unsigned char));
hash = calloc(SHA256_DIGEST_LENGTH, sizeof(char));
printf("Enter string:\n");
fgets((char*) data_to_hash, SHA256_DIGEST_LENGTH, stdin);
size_t len = strlen((const char*) data_to_hash);
SHA256(data_to_hash, len, (unsigned char*) hash);
printf("Hash: %s\n", hash);
return 0;
}
$ agcc -lcrypt -o test test.c
/usr/bin/ld: /tmp/ccjoZYK0.o: in function `main':
/home/narayan/Documents/BlockchainApps/test.c:18: undefined reference to `SHA256'
collect2: error: ld returned 1 exit status
#include <openssl/sha.h>
int SHA1_Init(SHA_CTX *c);
int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
int SHA1_Final(unsigned char *md, SHA_CTX *c);
unsigned char *SHA1(const unsigned char *d, size_t n,
unsigned char *md);
int SHA224_Init(SHA256_CTX *c);
int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA224_Final(unsigned char *md, SHA256_CTX *c);
unsigned char *SHA224(const unsigned char *d, size_t n,
unsigned char *md);
int SHA256_Init(SHA256_CTX *c);
int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA256_Final(unsigned char *md, SHA256_CTX *c);
unsigned char *SHA256(const unsigned char *d, size_t n,
unsigned char *md);
int SHA384_Init(SHA512_CTX *c);
int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA384_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA384(const unsigned char *d, size_t n,
unsigned char *md);
int SHA512_Init(SHA512_CTX *c);
int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA512_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA512(const unsigned char *d, size_t n,
unsigned char *md);
for(unsigned int j = 0; j < SHA256_DIGEST_LENGTH; j ++)
printf("%02hhX", hash[j]);
reinob wrote:Please note that you're defining "data_to_hash" as being able to hold SHA256_DIGEST_LENGTH -- that is 32 -- characters.
Given that you've defined BUFFER to be 256, I assume you want data_to_hash to be that size (you'd need to amend the fgets() call correspondingly).
Plus you surely don't want to just printf() the hash as a string, as the "characters" will range from 0 to 255, i.e. will generally not be printable.
You can do something like
- Code: Select all
for(unsigned int j = 0; j < SHA256_DIGEST_LENGTH; j ++)
printf("%02hhX", hash[j]);
PsySc0rpi0n wrote:reinob wrote:You can do something like
- Code: Select all
for(unsigned int j = 0; j < SHA256_DIGEST_LENGTH; j ++)
printf("%02hhX", hash[j]);
Ok, I tried that and it does what I was looking, but it handles chars individually. How can I pick up each char and save it into a string?
for(pos = 0; pos < SHA256_DIGEST_LENGTH; pos ++) {
string[2*pos] = ASCII code of higher 4-bits of hash[pos]
string[2*pos+1] = ASCII code of lower 4-bits of hash[pos]
}
reinob wrote:PsySc0rpi0n wrote:reinob wrote:You can do something like
- Code: Select all
for(unsigned int j = 0; j < SHA256_DIGEST_LENGTH; j ++)
printf("%02hhX", hash[j]);
Ok, I tried that and it does what I was looking, but it handles chars individually. How can I pick up each char and save it into a string?
When you wrote "I'm not a C++ guy at all" I took it to mean that you're a "C guy", but apparently you still have a long way to learn
So we'll leave that as an exercise OK?
(do ask if you have a specific problem, after you have read the C book and maybe google'd a bit
As a mere hint, you could use sprintf to store instead of printing.
The code would be elegant, but arguably bloated. Another option is to calculate, for each byte of the hash, the corresponding two ASCII characters of the hexadecimal representation, like:
- Code: Select all
for(pos = 0; pos < SHA256_DIGEST_LENGTH; pos ++) {
string[2*pos] = ASCII code of higher 4-bits of hash[pos]
string[2*pos+1] = ASCII code of lower 4-bits of hash[pos]
}
Hmm.. I think I wrote too much.
Good luck.
neuraleskimo wrote:I am happy to give pointers too, but I just don't have the bandwidth to teach C one compiler/linker error at a time. (I don't mean that as harsh as it probably sounds.) As reinob said K&R is your best starting point. However, let's take a slightly different approach...
Why use C for your program? There are other languages that you could use. If you want to learn C, that is a great reason! However, hashing strings may not be the best starter program.
PsySc0rpi0n wrote:I didn't understand what you mean with "I am happy to give pointers too..." You mean C pointers or that you like to point me in the right direction for the solution I need?
Users browsing this forum: No registered users and 3 guests