Reputation: 53
I have to convert the phrase '1234' into the Base64-encoding of its SHA-1 hash.
I want to have: '1234' = cRDtpNCeBiql5KOQsKVyrA0sAiA= (This example work in connection with the server communication)...
But when I checked it manualley on these sites or use my Methods in my XCode Project the result is always different:
1234
After SHA-1 (http://www.sha1.cz/) 7110eda4d09e062aa5e4a390b0a572ac0d2c0220
After Base64 (http://base64-encoder-online.waraxe.us/) NzExMGVkYTRkMDllMDYyYWE1ZTRhMzkwYjBhNTcyYWMwZDJjMDIyMA==
This is my SHA-1 function:
- (NSString *)sha1:(NSString *)str {
const char *cStr = [str UTF8String];
unsigned char result[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(cStr, strlen(cStr), result);
NSString *s = [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3], result[4],
result[5], result[6], result[7],
result[8], result[9], result[10], result[11], result[12],
result[13], result[14], result[15],
result[16], result[17], result[18], result[19]
];
return [s lowercaseString];
}
For Base64 I use a this class: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html
This is the call of SHA-1 and Base64:
NSString *pwHash =[self sha1:self._txtFieldPW.text]; //In my case '1234'
NSLog(@"Hash: %@",pwHash); //7110eda4d09e062aa5e4a390b0a572ac0d2c0220
//7110eda4d09e062aa5e4a390b0a572ac0d2c0220
NSData *pwHashData = [[NSData alloc]initWithData:[pwHash dataUsingEncoding:1]];
NSString *base64 = [pwHashData base64Encoding];
NSLog(@"Base64: %@",base64);
//NzExMGVkYTRkMDllMDYyYWE1ZTRhMzkwYjBhNTcyYWMwZDJjMDIyMA==
What is going wrong?
Upvotes: 2
Views: 4136
Reputation: 61396
Hash is a binary value. The "cRDtpNCeBiql5KOQsKVyrA0sAiA=" string is a result of the binary value of the hash, encoded. Meanwhile, the "NzExMGVkYTRkMDllMDYyYWE1ZTRhMzkwYjBhNTcyYWMwZDJjMDIyMA==" string is the result of the Base64 transform on the hexadecimal presentation of the hash.
Did that make sense? So you have a SHA1 hash, an array of 20 bytes: {0x71, 0x10, ...}. You can Base64-encode that chunk of memory as it is. Or you can convert each byte into two lowercase hex digits, then you'll get the ASCII string "7110eda4d09e062aa5e4a390b0a572ac0d2c0220". If you apply Base64 encoding to that string, as opposed to the original hash bytes, you'll get the Base64 value "NzExMGV...".
EDIT, with extra binary goodness: reformulate the second snippet thus:
unsigned char result[CC_SHA1_DIGEST_LENGTH];
const char *cStr = [self._txtFieldPW.text UTF8String];
CC_SHA1(cStr, strlen(cStr), result); //Now result contains the hash
//Wrap the result in a NSData object
NSData *pwHashData = [[NSData alloc] initWithBytes:result length: sizeof result];
//And take Base64 of that
NSString *base64 = [pwHashData base64Encoding];
NSLog(@"Base64: %@",base64);
And get rid of the sha1
method. Once you remove the monstrous stringWithFormat
call, it's a two-liner. If you really want the hex hash in the log, be my guest; but don't treat the hex string as the true value of the hash, 'cause it's not.
Unless you're using ARC, don't forget to free the NSData
object afterwards.
Upvotes: 9