2013-08-20 151 views
0

我需要將密碼轉換爲MD5哈希,並將其與我從Web服務獲得的MD5哈希進行比較。 如果這兩個匹配,用戶可以登錄。從字符串MD5哈希不匹配

假設用戶的密碼是'cat'。如果我做了一個哈希,我得到了d077f244def8a70e5ea758bd8352fcd8。這等於我從web服務收到的散列。現在我知道創建MD5的代碼是正確的。

但是,當密碼是'çàt',我得到這個哈希:727f8e931135b44b37eb147c8a7a56af。 web服務給我回這個哈希:f571ca52b4e3c5a6f49675deaea89cac

所以這就是問題所在。由於某些原因,這兩個同一個詞的哈希值是不同的,不知道這樣的事情甚至是可能的。 它只發生在密碼中有口音或其他奇怪的字符時,所以我認爲它與編碼有關。

我嘗試使用NSISOLatin1StringEncoding這樣的:

NSString *string = [NSString stringWithFormat:@"çàt"]; 

char converted[([string length] + 1)]; 
[string getCString:converted maxLength:([string length] + 1) encoding: NSISOLatin1StringEncoding]; 

NSString *converted_str = [NSString stringWithCString:converted encoding:NSISOLatin1StringEncoding]; 

這裏找到:Convert UTF-8 encoding to ISO 8859-1 encoding with NSString

但是,這並沒有給我正確的哈希無論是。

我嘗試了所有可能的NSString編碼,但沒有一個em返回正確的散列。

那麼我能做些什麼呢。用於轉換編碼的代碼有問題嗎?或者,它可能與編碼沒有任何關係(因爲嘗試其他編碼不起作用)?

+0

讓我們在Google中輸入'd077f244def8a70e5ea758bd8352fcd8',你就會明白爲什麼密碼不能用MD5散列,特別是沒有鹽。有像BCrypt或PBKDF2這樣的密鑰派生函數用於哈希密碼。 – martinstoeckli

回答

1

我會說727 ...你得到的是正確的,這是md5命令行工具給出的。所以這是你的服務器部分已經壞了 - 正如你已經說過的,這可能只是一些錯誤的編碼 - 在向服務器傳輸文本時要小心。

0

採用此方法返回在Objective-C的MD5散列字符串,前u必須導入公共的密碼庫

#import <CommonCrypto/CommonDigest.h> 

-(NSString*)md5HexDigest:(NSString*)input { 
const char* str = [input UTF8String]; 
unsigned char result[CC_MD5_DIGEST_LENGTH]; 
CC_MD5(str, strlen(str), result); 

NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2]; 
for(int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) { 
    [ret appendFormat:@"%02x",result[i]]; 
} 
return ret; 

}

然後確保你使用的是相同的編碼系統在這兩個部分,您的應用程序和您的Web服務,我建議使用「UTF-8」,但如果您使用的是「拉丁語1」,那麼在您的Web服務中,您應該使用「iso-850-1」

1

它確實必須處理文本編碼。請記住,MD5散列對字節起作用,而不是字符。因此,您輸入的文本的編碼很重要!

下面是散列爲您所看到的結果的字節序列:

d077f244def8a70e5ea758bd8352fcd8 = 63 61 74  ("cat", ASCII) 

727f8e931135b44b37eb147c8a7a56af = c3 a7 c3 a0 74 ("çát", UTF-8 NFC) 

f571ca52b4e3c5a6f49675deaea89cac = e7 e0 74  ("çát", ISO8859-1) 

雖然這方面的工作,請記住以下很重要的幾點:

  • 並不是所有的字符可以是代表ISO8859-1。它僅限於西歐語言中的字符。
  • 即使在UTF-8中,也可以有多個相同字符的表示形式。最值得注意的是,重音字符如「á」可以表示爲一個單獨的預先組合字符(U + 00E1 LATIN小字母A WITH ACUTE),或者作爲組合序列(U + 0061 LATIN小字母A + U + 0301組合急性口音)。結果看起來相同(á對á),但除非首先進行標準化,否則大多數比較例程以及哈希將被視爲不同的字符串。