-1

Quick question for those more experienced in c...

I want to compute a SHA256 checksum using the functions from openssl for the current time an operation takes place. My code consists of the following:

time_t cur_time = 0;
char t_ID[40];
char obuf[40];
char * timeBuf = malloc(sizeof(char) * 40 + 1);

sprintf(timeBuf, "%s", asctime(gmtime(&cur_time)));
SHA256(timeBuf, strlen(timeBuf), obuf);
sprintf(t_ID, "%02x", obuf);

And yet, when I print out the value of t_ID in a debug statement, it looks like 'de54b910'. What am I missing here?

  • Edited to fix my typo around malloc and also to say I expected to see the digest form of a sha256 checksum, in hex.
vergessen
  • 41
  • 1
  • 7
  • 2
    `malloc` takes a single argument. Post the code you're actually using. – a3f Mar 01 '17 at 23:41
  • 2
    What value did you expect it to have? – interjay Mar 01 '17 at 23:42
  • Where do you think you have code to print a 256-bit value? – David Schwartz Mar 02 '17 at 00:00
  • I thought that sprintf would take the value of obuf, format it appropriately and then put into t_ID. Apparently I'm way off, lol... – vergessen Mar 02 '17 at 00:03
  • Why do you want the hash of the current time? Have you considered that hash can be brute forced using a 'dictionary' attack, that is by trying all the possible time inputs. This is very practical considering the resolution of time_t is probably seconds. – jimhark Mar 02 '17 at 00:03
  • @jimhark, yes, that was considered. My first choice was to use the posix form of gettimeofday, which AFAIK allows for both seconds and nanoseconds, however, it conflicts with a mmm... home rolled version of time.h that I have to suffer with (not my choice). That said, the checksum here is only to be used in a brief transaction, no hashing passwords, nothing of that sort. Strictly I'm posting this to , and I want to use this hash as an identifier that I have done so. – vergessen Mar 02 '17 at 00:10
  • 1
    If you really need to hash a time stamp, why do you bother converting the numeric cur_time to a string? Any inconsistency in asctime you will cause you problems. Why not just hash cur_time directly? One thing you may have to account for is byte order, you can't allow your hash to change based on machine architecture. – jimhark Mar 02 '17 at 00:13
  • @jimhark, you might have guessed it, but I'm still relatively new to the nuances of c. That is, I know enough to get myself in trouble. So, to answer your previous question, I didn't know that I could take the output of gmtime(cur_time) and pass that as a param into SHA256. – vergessen Mar 02 '17 at 00:16
  • 1
    @vergessen You should probably post a new question then. Describe your use case and requirements in as much detail as you can and ask if SHA256 is a good solution and, if so, what to hash and what to do with the hash. – David Schwartz Mar 02 '17 at 01:34

2 Answers2

3

Since obuf is an array, printing its value causes it to decay to a pointer and prints the value of the memory address that the array is stored at. Write sensible code to print a 256-bit value.

Maybe something like:

for (int i = 0; i < 32; ++i)
    printf("%02X", obuf[i]);
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
0

This is not really intended as an answer, I'm just sharing a code fragment with the OP.

To hash the binary time_t directly without converting the time to a string, you could use something like (untested):

time_t cur_time;
char t_ID[40];
char obuf[40];

gmtime(&cur_time);
SHA256(&cur_time, sizeof(cur_time), obuf);

// You know this doesn't work:
// sprintf(t_ID, "%02x", obuf);

// Instead see https://stackoverflow.com/questions/6357031/how-do-you-convert-buffer-byte-array-to-hex-string-in-c

How do you convert buffer (byte array) to hex string in C?

This doesn't address byte order. You could use network byte order functions, see:

htons() function in socket programing http://beej.us/guide/bgnet/output/html/multipage/htonsman.html

One complication: the size of time_t is not specified, it can vary by platform. It's traditionally 32 bits, but on 64 bit machines it can be 64 bits. It's also usually the number of seconds since Unix epoc, midnight, January 1, 1970.

If you're willing to live with assumption that the resolution is seconds and don't have to worry about the code working in 20 years (see: https://en.wikipedia.org/wiki/Year_2038_problem) then you might use (untested):

#include <netinet/in.h>

time_t cur_time;
uint32_t net_cur_time; // cur_time converted to network byte order
char obuf[40];

gmtime(&cur_time);
net_cur_time = htonl((uint32_t)cur_time);
SHA256(&net_cur_time, sizeof(net_cur_time), obuf);

I'll repeat what I mentioned in a comment: it's hard to understand what you possibly hope to gain from this hash, or why you can't use the timestamp directly. Cryptographically secure hashes such as SHA256 go through a lot of work to ensure the hash is not reversible. You can't benefit from that because the input data is from a limited known set. At the very least, why not use CRC32 instead because it's much faster.

Good luck.

Community
  • 1
  • 1
jimhark
  • 4,938
  • 2
  • 27
  • 28