#objective-c #rest #hmac #sha256
#objective-c #rest #hmac #sha256
Вопрос:
Я работаю в Objective-C с REST API, который должен подписывать каждый HTTP-запрос в соответствии с этой спецификацией (https://web-payments.org/specs/source/http-signatures /).
Все это кажется простым, но у меня возникают проблемы с получением правильного значения «подписи». Я получаю разные результаты в Objective-C ПО сравнению с некоторыми из этих онлайн-генераторов sha (http://www.freeformatter.com/hmac-generator.html, http://hash.online-convert.com/sha256-generator ).
Я собрал некоторый изолированный тестовый код, чтобы разобраться с этим за пределами моего проекта.
Вот мой тестовый код:
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
NSString * hmacSHA256(NSString *key, NSString *data) {
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSMutableString *result = [NSMutableString string];
for(int i = 0; i < sizeof cHMAC; i ) {
[result appendFormat:@"x", cHMAC[i]];
}
return resu<
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSMutableString * data = [NSMutableString string];
[data appendString:@"(request-line) get /n"];
[data appendString:@"date: Wed, 02 Jul 2014 22:12:37 GMT"];
NSString * key = @"5a30f5477e2fdea27c5bdef8d5b0b13bfc8c2c77c608169da637a58ac0bff23895b58f8de5ef982a";
NSLog(@"%@",data);
NSString * signature = hmacSHA256(key,data);
NSLog(@"signature: %@",signature);
}
return 0;
}
Когда я запускаю этот тестовый код, я получаю это в качестве подписи:
8315081c226a7b0a77093cf12ec6ce4e112fedff12ddfcfd752c909b58a9ae5e
Но когда я вставляю эти строки:
(request-line) get /
date: Wed, 02 Jul 2014 22:12:37 GMT
К одному из онлайн-генераторов (http://www.freeformatter.com/hmac-generator.html, http://hash.online-convert.com/sha256-generator ) оба этих генератора дают мне одинаковую подпись:
71b09a1d0b8cde88f2b0c5bb78a06c4539994435e5e47700aa56d2194b9c2f08
Итак, как именно я должен преобразовать вышеупомянутую переменную «unsigned char cHMAC» в соответствующую строку?
Спасибо.
Комментарии:
1. Не уверен, что это реальная проблема, но разве ключ не должен быть шестнадцатеричным представлением фактического ключа, а не представлением ASCII? Т.Е. вам нужно декодировать шестнадцатеричное значение в байты?
2. Также я почти уверен, что «(строка запроса)» не должна включаться буквально, это просто означает, что вы должны включить саму строку запроса.
3. это не имеет значения для моего вопроса. важна разница между objc и онлайн-генераторами. Почему я не получаю одинаковые подписи. Входные данные одинаковы для каждого, почему разные результаты..
Ответ №1:
Ваша проблема в окончаниях строк в вашем тексте. На самом деле ваша программа генерирует правильный хэш, но вы вводите в веб-инструмент другую строку, поэтому и получаете другой результат. Вот текст, который вы отправляете в свою программу:
(request-line) get /ndate: Wed, 02 Jul 2014 22:12:37 GMT
И вот что вы отправляете в веб-инструмент (предполагая, что вы делаете это в Windows, которая проверяется на основе моих тестов):
(request-line) get /rndate: Wed, 02 Jul 2014 22:12:37 GMT
Обратите внимание на ‘ r n’. По умолчанию Windows (и, скорее всего, все веб-браузеры) использует возврат каретки И символ перевода строки в качестве последовательности EOL. Unix / Linux использует только перевод строки, а Mac использует только возврат каретки.
Если вы хотите проверить любые другие хэши, либо добавьте ‘ r’ в свою программу для тестирования, либо используйте программу, подобную Notepad , где вы можете управлять окончаниями строк для создания файлов, а затем загружать их на второй указанный вами сайт.
Комментарии:
1. На самом деле это не специфично для Windows (то же самое на Safari Mac здесь), это, вероятно, стандартно для
textarea
на всех платформах.2. да, это было так. как только я изменил n на r n, это была та же подпись.