2013-04-17 42 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