2013-12-06 2 views
1

Я работаю над библиотекой oauth для iOS, и от 10% до 15% моих запросов терпят неудачу, потому что oauth_signature, сгенерированный моей библиотекой, неверен. Я проследил проблему до CCHmac(), возвращая неожиданные результаты. Подпись терпит неудачу, когда hmac hash имеет неправильную длину. Чтобы проверить эту проблему, я побежал этот код:CCHmac с kCCHmacAlgSHA1 имеет несогласованную длину вывода

NSString *key = @"25f108b539761bd43b6c66b64fb191c8"; 

for (int i = 0; i < 25; i++) { 
    unsigned int chunks[4] = { 
     arc4random() % ((int) pow(256, 4)), 
     arc4random() % ((int) pow(256, 4)), 
     arc4random() % ((int) pow(256, 4)), 
     arc4random() % ((int) pow(256, 4)) 
    }; 

    // Generate a random input string of 32 hex chars 
    NSString *input = [NSString stringWithFormat:@"%08x%08x%08x%08x", chunks[0], chunks[1], chunks[2], chunks[3]]; 

    unsigned char output[CC_SHA1_DIGEST_LENGTH]; 

    CCHmac(kCCHmacAlgSHA1, key.UTF8String, key.length, input.UTF8String, input.length, output); 

    NSLog(@"HMAC Hash Length: %02lu", strlen(output)); 
} 

... и получил этот результат:

2013-12-06 16:05:24.596 ODB[98281:70b] HMAC Hash Length: 40 
2013-12-06 16:05:24.596 ODB[98281:70b] HMAC Hash Length: 20 
2013-12-06 16:05:24.596 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.596 ODB[98281:70b] HMAC Hash Length: 35 
2013-12-06 16:05:24.596 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.597 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.597 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.597 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.597 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.597 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.597 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.597 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.598 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.598 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.598 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.598 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.795 ODB[98281:70b] HMAC Hash Length: 20 
2013-12-06 16:05:24.795 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.795 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.795 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.796 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.796 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.796 ODB[98281:70b] HMAC Hash Length: 41 
2013-12-06 16:05:24.796 ODB[98281:70b] HMAC Hash Length: 24 
2013-12-06 16:05:24.797 ODB[98281:70b] HMAC Hash Length: 41 

Этот метод HMAC хеширования, кажется, довольно общепризнанной, поэтому я бы ожидать, что в соответствии выходная длина. Что мне не хватает?

ответ

1

Если я правильно помню, CCHmac выводит свой результат в двоичной форме, поэтому, когда эта функция заканчивается, вывод [] всегда должен быть заполнен точно 20 байтов.

Напомним, что strlen() просто выполняет итерацию по памяти до тех пор, пока не найдет «нулевой» байт, например.

int strlen(char *s) 
{ 
    for(int n = 0; s[n] != 0; s++) 
    { 
    n++; 
    } 
    return n; 
} 

Так что, если это произойдет, что один из байтов в выходной [] = 0, то ваше заявление NSLog напечатает значение меньше 20. В противном случае, STRLEN() будет продолжать поиск в неопределенных области памяти пока не произойдет где-то найти значение 0. Вы получите в значительной степени непредсказуемые результаты, и это может привести к сбою вашей программы.

Вместо этого, похоже, что вы можете ожидать шестнадцатеричное представление HMAC. Чтобы получить его, вы можете сделать что-то вроде:

NSMutableString *hexOutput = [NSMutableString string]; 
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { 
    [hexOutput appendFormat:@"%02x", output[i]]; 
} 
Смежные вопросы