SHA1 hash difference between c# windows store app and Objective-c iOS -
my windows store app on surface pro uses sha1 send hashed password server. wanted same thing ios app different results , don't know why.
i tried different encoding (nsascii utf8 unicode) when converting nsstrings cstring no prevail.
c# windows store app - surface pro
/// <summary> /// literal copy of values web config machinekey /// </summary> const string validationkey = "6db51f17c529ad3cabec50b3c89cb21f4f1422f58a5b42d0e8db8cb5cda146511891c1baf47f8d29401e3400267682b202b7da146511891c1baf47f8d29401e3"; public static string hmacsha1(string basestring) { var crypt = macalgorithmprovider.openalgorithm("hmac_sha1"); var buffer = cryptographicbuffer.createfrombytearray(encoding.unicode.getbytes(basestring)); var keybuffer = windows.security.cryptography.cryptographicbuffer.createfrombytearray(hextobyte(validationkey)); var key = crypt.createkey(keybuffer); var sigbuffer = cryptographicengine.sign(key, buffer); string signature = cryptographicbuffer.encodetobase64string(sigbuffer); return signature; } // // hextobyte // converts hexadecimal string byte array. used convert encryption // key values configuration. // private static byte[] hextobyte(string hexstring) { byte[] returnbytes = new byte[hexstring.length / 2]; (int = 0; < returnbytes.length; i++) returnbytes[i] = convert.tobyte(hexstring.substring(i * 2, 2), 16); return returnbytes; } objective-c ios
//hash password nsstring *secret = @"6db51f17c529ad3cabec50b3c89cb21f4f1422f58a5b42d0e8db8cb5cda146511891c1baf47f8d29401e3400267682b202b7da146511891c1baf47f8d29401e3"; nsstring *data = password; const char *ckey = [secret cstringusingencoding:nsasciistringencoding]; const char *cdata = [data cstringusingencoding:nsasciistringencoding]; unsigned char chmac[cc_sha1_digest_length]; cchmac(kcchmacalgsha1, ckey, strlen(ckey), cdata, strlen(cdata), chmac); nsdata *hmac = [[nsdata alloc] initwithbytes:chmac length:sizeof(chmac)]; nsstring *signature = [hmac base64encodedstringwithoptions:0]; nsstring *clientpassword = signature;
so genius helped me figure out. in c# code password encoded unicode can seen in line:
encoding.unicode.getbytes(basestring) that means should have changed nsascii encoding line in objective-c to:
const char *cpassword = [password cstringusingencoding:nsunicodestringencoding]; now comes tricky. unicode encodes string 'welkom123' this: w/0e/0l/0k/0o/0m/01/02/03/0. means can't use strlen(cdata) determine length of cdata because stop counting when encountering /0, length has been wrong whole time. had replace strlen(cdata) (password.length * 2).
but outcome still not right. key had become hexadecimal data in c# code. nsdata should used create cchmac. code turns nsstring nsdata hexadecimal values:
int len = (int)([inputstring length] / 2); // target length unsigned char *buf = malloc(len); unsigned char *whole_byte = buf; char byte_chars[3] = {'\0','\0','\0'}; int i; (i=0; < [inputstring length] / 2; i++) { byte_chars[0] = [inputstring characteratindex:i*2]; byte_chars[1] = [inputstring characteratindex:i*2+1]; *whole_byte = strtol(byte_chars, null, 16); whole_byte++; } nsdata *data = [nsdata datawithbytes:buf length:len]; free( buf ); return data; in end total code this:
-(nsdictionary *)authenticatewithusername:(nsstring *)username andpassword:(nsstring *)password andsyncurl:(nsstring *)syncurl { nsstring *key = @"6db51f17c529ad3cabec50b3c89cb21f4f1422f58a5b42d0e8db8cb5cda146511891c1baf47f8d29401e3400267682b202b7da146511891c1baf47f8d29401e3"; nsdata *data = [self stringtohexdata:key]; const char *cpassword = [password cstringusingencoding:nsunicodestringencoding]; unsigned char chmac[cc_sha1_digest_length]; cchmac(kcchmacalgsha1, data.bytes, data.length, cpassword, (password.length * 2), chmac); nsdata *hmac = [[nsdata alloc] initwithbytes:chmac length:sizeof(chmac)]; nsstring *hashedpassword = [hmac base64encodedstringwithoptions:0]; nsstring *clientpassword = hashedpassword; // code here left out readability sake return dict; } - (nsdata *) stringtohexdata:(nsstring *)inputstring { int len = (int)([inputstring length] / 2); // target length unsigned char *buf = malloc(len); unsigned char *whole_byte = buf; char byte_chars[3] = {'\0','\0','\0'}; int i; (i=0; < [inputstring length] / 2; i++) { byte_chars[0] = [inputstring characteratindex:i*2]; byte_chars[1] = [inputstring characteratindex:i*2+1]; *whole_byte = strtol(byte_chars, null, 16); whole_byte++; } nsdata *data = [nsdata datawithbytes:buf length:len]; free( buf ); return data; }
Comments
Post a Comment