2013-04-17 65 views
1

基本上我想編寫計算sha1哈希的函數。在Objective-C和C#.NET中產生不同結果的SHA1哈希

到目前爲止我試過的如下。

C#的.NET

byte[] p2 = System.Text.Encoding.Unicode.GetBytes("password"); 
System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider(); 
byte[] result = sha.ComputeHash(p2); 
string encodedPassword = Convert.ToBase64String(result); 

輸出: 6Pl/upEE0epQR5SObftn + s2fW3M =

目標C

我已經加入類的Base64從NSData_Base64 Classes reference

NSString *password = @"password"; 
NSData *data = [password dataUsingEncoding:NSUTF8StringEncoding]; 
NSString *unicodePassword = [[NSString alloc] initWithData:data encoding:NSUnicodeStringEncoding]; 
data = [unicodePassword dataUsingEncoding:NSUnicodeStringEncoding]; 


unsigned char hash[CC_SHA1_DIGEST_LENGTH]; 
CC_SHA1([data bytes], [data length], hash); 
NSData *result = [NSData dataWithBytes:hash length:CC_SHA1_DIGEST_LENGTH]; 
NSLog(@"Result: %@",[result base64EncodedString]); 

輸出: dYusXVhObIBzJMgg1E1FJ9cK1NY =

任何人都可以請建議我究竟做錯了什麼?

爲什麼這兩個值有所不同?

請糾正我的錯誤。

+0

也許「NSData_Base64類參考」使用URL安全的base64,但C#.NET的System.Security.Cryptography.SHA1與URL不安全的一起工作?嘗試使用聯機SHA1加密器/解密器來比較結果。我建議使用可在此處找到的GData Base64:https://code.google.com/p/gdata-objectivec-client/。 –

回答

3

這條線是錯誤的,因爲您解釋UTF8編碼數據,如果它是Unicode的編碼:

NSString *unicodePassword = [[NSString alloc] initWithData:data encoding:NSUnicodeStringEncoding];

Replce第二符合: NSData *data = [password dataUsingEncoding:NSUnicodeStringEncoding];

的2個第一字節中的數據是BOM(字節順序標記)。

data = [NSData dataWithBytes:[data bytes] + 2 length:[data length] - 2];

刪除這2個字節......然後散列這些數據的任何你將有相同的散列爲C#。

+0

我試過但不工作的輸出是RsVAbAblCcyoeiKAeH + 6zWWZ6Ok = now。 –

+0

編輯關於如何刪除BOM的帖子。 – Markus

+0

哇!感謝這是工作。您能否詳細說明什麼是「字節順序標記」以及如何檢測並解決它? –

1

欲瞭解更多信息,我發現,SHA1功能可以有一些結果..

在此鏈接所以我已經實現的方法:MD5 and SHA1 iOS implementation通過this stackoverflow question

聯繫,我和我的那個集成的形式發送參數來調整它如果您發送UTF8編碼字符串或沒有(unicode的一種),如果你想十六進制字符串或十進制一個

- (NSString*) sha1UTF8Encoding:(BOOL)utf8 andDecimal:(BOOL)decimal 
{ 
    const char *cstr; 
    if (utf8) { 
     cstr = [self cStringUsingEncoding:NSUTF8StringEncoding]; 
    }else{ 
     cstr = [self cStringUsingEncoding:NSUnicodeStringEncoding]; 
    } 
    NSData *data = [NSData dataWithBytes:cstr length:self.length]; 

    uint8_t digest[CC_SHA1_DIGEST_LENGTH]; 

    CC_SHA1(data.bytes, data.length, digest); 

    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; 

    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++){ 
     if (decimal) { 
      [output appendFormat:@"%i", digest[i]]; 
     }else{ 
      [output appendFormat:@"%02x", digest[i]]; 
     } 
    } 

    return output;  
} 

(請注意,我實現了一個NSString的類別此方法)

有了這個我測試可以使用此配置將它用於許多目的SHA1操作,例如:

NSString* sha1 = [stringToTest sha1UTF8Encoding:YES andDecimal:YES]; 

SHA1可變匹配與所述一個產物由C#方法在此鏈接發現:Hashing using the SHA1 class