简体   繁体   中英

Discrepancy between C# MD5 and Objective C MD5

I am trying to communicate with a C# service from a native iPhone application. In order to communicate the password entered needs to be hashed and compared against the hashed version that is stored on the server. I am attempting to recreate the C# hash in Objective C and that's where it starts to get interesting

Objective C Code:

NSString * password = @"testPass123";
const char *cPassword = [password UTF8String];    

NSString * key = @"Garbage12345";
NSData * keyData = [NSData dataFromBase64String:key];
NSUInteger len = [keyData length];
unsigned char * cKey = (unsigned char *)malloc(len);
memcpy(cKey, [keyData bytes], len);

// Concatenate into one byte array
unsigned char totalString[18];
for (int i = 0; i < strlen(cPassword); i++) {
    totalString[i] = cPassword[i];
}

for (int i = 0; i < len; i++) {
    totalString[strlen(cPassword) + i] = cKey[i];
}

// DEBUG: Display byte array
for (int i = 0; i < 18; i++) {
    NSLog(@"totalString: %x", totalString[i]);
}

// **** totalString == plainTextWithSaltBytes from the C# portion ****
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(totalString, CC_MD5_DIGEST_LENGTH, result);

for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
    NSLog(@"result: %02x", result[i]);
}

C# Code:

byte[] SaltBytes = Convert.FromBase64String("Garbage12345");

// Convert plain text into a byte array.
byte[] plainTextBytes = Encoding.UTF8.GetBytes("testPass123");

// Allocate array, which will hold plain text and salt.
byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + SaltBytes.Length];

// Copy plain text bytes into resulting array.
for (int i = 0; i < plainTextBytes.Length; i++)
    plainTextWithSaltBytes[i] = plainTextBytes[i];

// Append salt bytes to the resulting array.
for (int i = 0; i < SaltBytes.Length; i++)
    plainTextWithSaltBytes[plainTextBytes.Length + i] = SaltBytes[i];

HashAlgorithm hash = new MD5CryptoServiceProvider();

// **** plainTextWithSaltBytes == totalString from the Obj-C portion ****
// Compute hash value of our plain text with appended salt.
byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

// Convert result into a base64-encoded string.
string hashValue = Convert.ToBase64String(hashBytes);

I get back the same results for the byte array before it goes into the MD5 portion of either. Using the dummy data supplied it returns:

74
65
73
74
50
61
73
73
31
32
33
19
aa
db
6a
07
b5
db

However, afterwards I get back different values and am not sure where to go from there.

Anyone have any ideas? Feel free to point out things I'm doing wrong as well. Thanks.

I suspect your bug is that the second parameter of CC_MD5 should be the input and not the output length. Passing in the input length should fix your immediate problem.

But I think, that you should throw away the code on both sides, and use some function designed for password hashing. Such as PBKDF2 or bcrypt.

It's also strange that you send the hash to the server. Normally you send the password to the server and hash it there. Sending the hash essentially changed the definition of the password, and allows login for an attacker who doesn't know the password but knows the hash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM