iOS / Цель C: SHA-1 и Base64 - PullRequest
       56

iOS / Цель C: SHA-1 и Base64

2 голосов
/ 05 сентября 2011

Мне нужно преобразовать фразу '1234' в кодировку Base64 его хэша SHA-1.

Я хочу получить: '1234' = cRDtpNCeBiql5KOQsKVyrA0sAiA = (Этот пример работает в связи с серверомсвязь) ...

Но когда я проверял это вручную на этих сайтах или использовал мои методы в моем проекте XCode, результат всегда был другим:

1234

После SHA-1 (http://www.sha1.cz/) 7110eda4d09e062aa5e4a390b0a572ac0d2c0220

после Base64 (http://base64 -encoder-online.waraxe.us / ) NzExMGVkYTRkMDllMWYYYJJYJJJJYHYHYHWHWHWHYHWHWHWHWHWHWHWB-1 функция:

- (NSString *)sha1:(NSString *)str {
    const char *cStr = [str UTF8String];
    unsigned char result[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(cStr, strlen(cStr), result);
    NSString *s = [NSString  stringWithFormat:
                   @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
                   result[0], result[1], result[2], result[3], result[4],
                   result[5], result[6], result[7],
                   result[8], result[9], result[10], result[11], result[12],
                   result[13], result[14], result[15],
                   result[16], result[17], result[18], result[19]
                   ];

    return [s lowercaseString];
}

Для Base64 я использую этот класс: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html

Это вызов SHA-1 и Base64:

 NSString *pwHash =[self sha1:self._txtFieldPW.text]; //In my case '1234'
 NSLog(@"Hash: %@",pwHash); //7110eda4d09e062aa5e4a390b0a572ac0d2c0220
 //7110eda4d09e062aa5e4a390b0a572ac0d2c0220
 NSData *pwHashData = [[NSData alloc]initWithData:[pwHash dataUsingEncoding:1]];
 NSString *base64 = [pwHashData base64Encoding];
 NSLog(@"Base64: %@",base64); 
 //NzExMGVkYTRkMDllMDYyYWE1ZTRhMzkwYjBhNTcyYWMwZDJjMDIyMA==

Что не так?

1 Ответ

9 голосов
/ 05 сентября 2011

Хеш - это двоичное значение. Строка "cRDtpNCeBiql5KOQsKVyrA0sAiA =" является результатом двоичного значения закодированного хэша. Между тем строка «NzExMGVkYTRkMDllMDYyYWE1ZTRhMzkwYjBhNTcyYWMwZDJjMDIyMA ==» является результатом преобразования Base64 в шестнадцатеричном представлении хеша.

Это имело смысл? Итак, у вас есть хеш SHA1, массив из 20 байтов: {0x71, 0x10, ...}. Вы можете закодировать в Base64 этот кусок памяти как есть. Или вы можете преобразовать каждый байт в две шестнадцатеричные строчные буквы, после чего вы получите строку ASCII "7110eda4d09e062aa5e4a390b0a572ac0d2c0220". Если вы примените кодировку Base64 к этой строке , в отличие от исходных хеш-байтов, вы получите значение Base64 "NzExMGV ...".

РЕДАКТИРОВАТЬ, с дополнительным бинарным совершенством: переформулируйте второй фрагмент следующим образом:

unsigned char result[CC_SHA1_DIGEST_LENGTH]; 
const char *cStr = [self._txtFieldPW.text UTF8String];
CC_SHA1(cStr, strlen(cStr), result); //Now result contains the hash

//Wrap the result in a NSData object
NSData *pwHashData = [[NSData alloc] initWithBytes:result length: sizeof result];  
//And take Base64 of that
NSString *base64 = [pwHashData base64Encoding];  
NSLog(@"Base64: %@",base64); 

И избавьтесь от метода sha1. Как только вы уберете чудовищный вызов stringWithFormat, он станет двухсторонним. Если вы действительно хотите использовать шестнадцатеричный хэш в журнале, будьте моим гостем; но не рассматривайте шестнадцатеричную строку как истинное значение хеша, потому что это не так.

Если вы не используете ARC, не забудьте впоследствии освободить объект NSData.

...