0

I am attempting to convert an HMAC (hashed data) to a string safe for urls for authentication purposes.

Im having problems converting data generated from sha256 hashing (using apples crypto library) to Unicode in both little and big Endian, one hashed string will work in big and not in little, and visa versa for a different hashed string. For some hashed strings it works perfectly. I think it may have something to do with an out of range character or something. When I say it doesn't work, I mean it returns nil.

The code looks like this:

NSString *mystring = [[NSString alloc] initWithData:myHash encoding:NSUnicodeEncoding

Is Unicode the best to use? I tried encoding to UTF8, it returns nil and ascii doesn't have all the characters, I get a few "?" where data is missing.

Really, my question is, how do I make A string from NSData from a sha256 hash?


Solution:

https://github.com/eczarny/xmlrpc

NSData+Base64.h and NSData+Base64.m

MrJD
  • 1,879
  • 1
  • 23
  • 40
  • 1
    The result of a cryptographic hash is pure binary data without any encoding. And NSString instances have no encoding either. So all encodings are wrong. Jonas Schnelli's Solution is one approach. A Base64 conversion would be another one. – Codo Apr 16 '12 at 11:54
  • @Codo can you recommend a base64 encoder for objective c? Or is there one built into Cocoa? – MrJD Apr 16 '12 at 12:36
  • I can't recommend a specific one. But this [question and answers](http://stackoverflow.com/questions/392464/any-base64-library-on-iphone-sdk) provide several ones. – Codo Apr 16 '12 at 13:47

1 Answers1

1

You first need to make a hex string out of your HMAC bytes. You can make it like this:

void bytes_to_hexstring(void *uuid, char *hex_string, size_t osize) {
    static const char hexdigits[] = "0123456789ABCDEF";
    const unsigned char* bytes = (unsigned char *)uuid;

    int i = 0;
    for (i = 0; i<osize; ++i) {
        const unsigned char c = *bytes++;
        *hex_string++ = hexdigits[(c >> 4) & 0xF];
        *hex_string++ = hexdigits[(c ) & 0xF];
    }
    *hex_string = 0;
}

char *mystring = malloc(41);
bytes_to_hexstring(myHash, mystring, 20);

something like this.
Jonas Schnelli
  • 9,965
  • 3
  • 48
  • 60
  • Is this a base 64 encoding? I need to set it up to be decoded on the other end – MrJD Apr 16 '12 at 12:31
  • Yes. Its base64. You can do a base64unencode on your server when you need rawbytes again. – Jonas Schnelli Apr 16 '12 at 13:26
  • @JonasSchnelli: No, it's not. Your answer proposes a hexadecimal representation, not a Base 64 representation. They are two different kinds. – Codo Apr 16 '12 at 13:45
  • Oops. Yes Coda is right. It's a HEX representation of the string. But you can also use bas64encoding (and decoding on the server). Check this [post](http://stackoverflow.com/questions/2197362/converting-nsdata-to-base64). – Jonas Schnelli Apr 16 '12 at 14:31