Converting hex to base64 in Objective C? - iphone

I had created a SHA256 encoding of the string using the following function,
const char *s=[#"123456" cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData=[NSData dataWithBytes:s length:strlen(s)];
uint8_t digest[CC_SHA256_DIGEST_LENGTH]={0};
CC_SHA256(keyData.bytes, keyData.length, digest);
NSData *out=[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
NSString *hash=[out description];
hash = [hash stringByReplacingOccurrencesOfString:#" " withString:#""];
hash = [hash stringByReplacingOccurrencesOfString:#"<" withString:#""];
hash = [hash stringByReplacingOccurrencesOfString:#">" withString:#""];
NSLog(#"Hash : %#", hash);
It gives me the output : 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92.
But I need the following output : jZae727K08KaOmKSgOaGzww/XVqGr/PKEgIMkjrcbJI=. It's base64.
How Can I convert the "hex" hash I generated to "base64"?
I had use this website to generate base64 hash : http://www.online-convert.com/result/7bd4c809756b3c16cf9d1939b1e57584

You should not be converting the NSString *hash that you generated from the description to base-64. It is a hex string, not the actual data bytes.
You should go straight from NSData *out to base-64 string, using any of the available base-64 encoders. For example, you can download an implementation from this post, and use it as follows:
const char *s=[#"123456" cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData=[NSData dataWithBytes:s length:strlen(s)];
uint8_t digest[CC_SHA256_DIGEST_LENGTH]={0};
CC_SHA256(keyData.bytes, keyData.length, digest);
NSData *out=[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
// The method below is added in the NSData+Base64 category from the download
NSString *base64 =[out base64EncodedString];

I use this, (mentionned in How do I do base64 encoding on iphone-sdk?)
http://www.imthi.com/blog/programming/iphone-sdk-base64-encode-decode.php
Works well, and easily usable with ARC.

Related

EXC_BAD_ACCESS on CCHmac

i am doing HMAC-SHA256 encoding . Tried but didn't find any solutions.
#include <CommonCrypto/CommonHMAC.h>
- (NSString *)hmacWithKey:(NSString *)key andData:(NSString *)data
{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
///////////////////////////////////////////////////////////////
////but on below line of code i am getting EXC_BAD_ACCESS//////
///////////////////////////////////////////////////////////////
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
//////////////////////////////////////////////
NSData *out = [NSData dataWithBytes:cHMAC length:CC_SHA256_DIGEST_LENGTH];
// description converts to hex but puts <> around it and spaces every 4 bytes
NSString *hash = [out description];
hash = [hash stringByReplacingOccurrencesOfString:#" " withString:#""];
hash = [hash stringByReplacingOccurrencesOfString:#"<" withString:#""];
hash = [hash stringByReplacingOccurrencesOfString:#">" withString:#""];
// hash is now a string with just the 40char hash value in it
NSLog(#"%#",hash);
return hash;
}
Please tell me whats wrong i am doing here.
Thanks
cStringUsingEncoding:NSASCIIStringEncoding can return NULL if the string contains non-ASCII characters.
Therefore you should check if cKey == NULL or cData == NULL.
Or better, convert to UTF-8 strings:
const char *cKey = [key UTF8String];
const char *cData = [data UTF8String];
I ran the OPs code with sample strings with no error so the error must be in the input. Either one or more of the inputs is nil or non-ascii.
Please provide sample input that fails.
BTW, it is not necessary to use char strings, here is an example using NSData:
NSData *cKey = [key dataUsingEncoding:NSUTF8StringEncoding];
NSData *cData = [data dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *out = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey.bytes, cKey.length, cData.bytes, cData.length, out.mutableBytes);
NSLog(#"out: %#", out);

Encoding hex value with UTF8 of Ascii representation

I have a nsdata with bytes :0017c572 528e
now i need to encode this byte using either UTF 8 of Ascii
For this i have used following code in Objective C
NSString *Str = [[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding];
then later on at some point i need to get back the same bytes from Str for this i have used
NSData *aData = [Str dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"aData:%#", aData);
Now the problem is content of aData is null not 0017c572 528e . how can i do the this operation.
this concept works perfectly if data byte is : 323332
str = 232
aData = 323332
Just print the Str value before the line
NSLog(#"Str = %#",Str);
NSData *aData = [Str dataUsingEncoding:NSUTF8StringEncoding];
It seems the Str variable does not have any value. Then only, it will return null. Please check.

AES Encryption using IV, Salt, RFC2898 iteration, Key Generation using SHA1 algorithm in iPhone

I have a problem related to AES Encryption. The problem is I need to encrypt the string using AES encryption technique with Intialization Vector, Salt, RFC2898 iteration and Generate a key using sha1 algorithm.
I used this code
+(NSString *)stringToSha1:(NSString *)str{
const char *s = [str cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData = [NSData dataWithBytes:s length:strlen(s)];
// This is the destination
uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0};
// This one function does an unkeyed SHA1 hash of your hash data
CC_SHA1(keyData.bytes, keyData.length, digest);
// Now convert to NSData structure to make it usable again
NSData *out = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
// description converts to hex but puts <> around it and spaces every 4 bytes
NSString *hash = [out description];
hash = [hash stringByReplacingOccurrencesOfString:#" " withString:#""];
hash = [hash stringByReplacingOccurrencesOfString:#"<" withString:#""];
hash = [hash stringByReplacingOccurrencesOfString:#">" withString:#""];
NSLog(#"Hash is %# for string %#", hash, str);
return hash;
}
For sha1 key generation but it produces totally different as this technique do in .net and Android.
Android and .net already have classes and library to do this and i left alone so how I can do it in iPhone.
This should be what you need
+ (NSData *)sha1HashFromString:(NSString *)stringToHash {
NSData *stringData = [stringToHash dataUsingEncoding:NSASCIIStringEncoding];
uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0};
CC_SHA1([stringData bytes], [stringData length], digest);
NSData *hashedData = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
return [hashedData autorelease];
}

php to iphone code - CCHmac kCCHmacAlgSHA256

I am trying to login to my server using hmac sha256 encryption, i have working code in php, but can't get it working in iphone and traced it to that the hmac in iphone is yielding different output to php code, given same inputs
php code is
$privatekey = '6-y6f"\%BjSM;HBo\'sPr")5#t2nb-LG*;])f^Si[';
$identity_arrow_getSecret = $privatekey;
$date_c = "2011-04-18T23:56:28+0800";
$uri = '/backend/1/User/Header';
$stringToSign = "GET\n\n\n" . $date_c . "\n" . $uri;
$signature = hash_hmac("sha256", utf8_encode($stringToSign), $identity_arrow_getSecret);
echo "stringToSign is $stringToSign <HR>";
echo "signature is $signature <HR>";
objective-c code is
NSString* uri = #"/backend/1/User/Header";
NSString* date_c = #"2011-04-18T23:56:28+0800"; //[dateFormatter stringFromDate:[NSDate date]];
NSString* stringToSign = [NSString stringWithFormat:#"GET\n\n\n%#\n%#" , date_c , uri];
NSLog(#" stringToSign : %# <>\r\n", stringToSign);
NSString* privatekey = #"6-y6f\"\%BjSM;HBo\'sPr\")5#t2nb-LG*;])f^Si[";
const char *cKey = [privatekey cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [stringToSign cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSString *hash = [HMAC base64EncodedString];
NSLog(#" hash : %# \r\n", hash);
You may want to check your Base64 class. I use the Base64 class written by Kiichi Takeuchi and it gives me identical results to a routine I wrote in C# to verify, so I assume it's correct.
I had to make one small change to your code to verify, as the Base64 library only encodes an NSData structure. Here's what it looks like:
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *nsd = [[NSData alloc] initWithBytes: cHMAC length:CC_SHA256_DIGEST_LENGTH];
NSString *hash = [Base64 encode:nsd];
[nsd release];
NSLog(#" hash : %# \r\n", hash);

hash a password string using SHA512 like C#

I am developing logon function for my iPhone Application, so I want to hash the password using the SHA512 hashing algorithm then get the result as NSString (the result should be the same with SHA512 in C#). After spending a lot of time in the internet, I still not find out the solution yet! :(
Is there anyone has the solution and sample code, please help me!
Thanks a lot!
[Update]
In my C# code, the password is stored using SecureString, so maybe it's cause make different byte array between objective-c and C#
This function will hash a string using SHA512. The resulting string is a hex representation of the hash:
+ (NSString *) createSHA512:(NSString *)source {
const char *s = [source cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData = [NSData dataWithBytes:s length:strlen(s)];
uint8_t digest[CC_SHA512_DIGEST_LENGTH] = {0};
CC_SHA512(keyData.bytes, keyData.length, digest);
NSData *out = [NSData dataWithBytes:digest length:CC_SHA512_DIGEST_LENGTH];
return [out description];
}
Don't forget to include the correct header:
#include <CommonCrypto/CommonDigest.h>
I am using this one.
It matches PHP SHA512 algorithm output:
<?php `hash('sha512', 'The quick brown fox jumped over the lazy dog.');` ?>
Objective-C code:
+(NSString *)createSHA512:(NSString *)string
{
const char *cstr = [string cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:string.length];
uint8_t digest[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x", digest[i]];
return output;
}