Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obj-C MD5 Hash not matching Java / SQL

I'm trying to take a unicode string, pass it through an MD5 hash function, and encode the result as Base64. I need MSSQL, Java and Obj-C to all return the same result. I have MSSQL and Java agreeing, but I cannot get the same result using Obj-C.

Java code (returns "SC0RfYWqWLK/YNpIDdGi8w==")

String input = "chinese lorem ipsum 槏殟殠巘斖蘱飣偓啅撱簻臗";
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] inputBytes = input.getBytes("UTF-16LE");
md.update(input.getBytes("UTF-16LE"));
byte[] enc = md.digest();
String md5Sum = new sun.misc.BASE64Encoder().encode(enc);
System.out.println(md5Sum);

MSSQL code (returns "SC0RfYWqWLK/YNpIDdGi8w==")

DECLARE @Str nvarchar(200)
SET @Str = N'chinese lorem ipsum 槏殟殠巘斖蘱飣偓啅撱簻臗'
DECLARE @Bin varbinary(max)
SET @Bin = HashBytes('MD5', @Str);
DECLARE @Hash char(24)
SET @Hash = CAST(N'' AS XML).value('xs:base64Binary(sql:variable("@Bin"))', 'NVARCHAR(MAX)')
PRINT @Hash

Obj-C code (returns "vZRPxuE84whftlx697i/Ig==")

NSString *input = @"chinese lorem ipsum 槏殟殠巘斖蘱飣偓啅撱簻臗";
NSData *data = [input dataUsingEncoding:NSUnicodeStringEncoding allowLossyConversion:NO];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5(data.bytes, data.length, digest);
NSData *hashData = [[NSData alloc] initWithBytes:digest length: sizeof digest];
NSString *base64 = [hashData base64EncodedString];
NSLog(@"%@", base64);

Please could you help me get Obj-C to return the same value as the others. It will be running in iOS app. Thanks.

like image 667
UserNYC Avatar asked Aug 09 '12 14:08

UserNYC


2 Answers

Not an expert here, but just a guess - have you tried using NSUTF16LittleEndianStringEncoding encoding for initialising data from string?

like image 156
Eimantas Avatar answered Oct 20 '22 23:10

Eimantas


I suspect the problem may be that Java and MSSQL do not add a byte order mark to the beginning of the string, while dataUsingEncoding:allowLossyConversion: with NSUnicodeStringEncoding does.

You can verify this by checking the size (and maybe even the actual content, if this turns out not to be the problem) of the actual UTF-16 data in java and objective-c.

like image 1
Analog File Avatar answered Oct 20 '22 22:10

Analog File