Генерация SHA256 в iphone/Objective C ...?
Как создать строку SHA256 в iphone/ объективе...
Sha256 в Objective-C для iPhone
Я прочитал это.. но я не в состоянии понять это..
Я хочу создать вывод, похожий на функцию php следующим образом:
$hash = hash_hmac("sha256", implode(';', $hash_parameters), $api_key);
где хэш-параметры - это массив аргументов...
Можете ли вы написать это как метод, который будет принимать входную строку...?
А что будет выводом метода NSData или NSString..??
Я должен создать запрос с этим..??
Так в объекте запроса..
[theRequest setHTTPBody:requestBody];
какой должен быть тип запроса тела??
5 ответов
Я не уверен, что полностью понимаю ваши вопросы, но если вы хотите создать хеш-строку, вы МОЖЕТЕ передать свои параметры в качестве аргументов хэш-функции.
-(void)generateHashedString {
NSString *key = @"Some random string";
//enter your objects you want to encode in the data object
NSString *data = [NSString stringWithFormat:@"%@%@%@", @"sha256", hash_parameters, api_key];
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);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
length:sizeof(cHMAC)];
NSString *hash = [HMAC base64Encoding];
}
Это даст вам NSString хэша, который вы можете использовать для выполнения ваших запросов. NSLog(@"%@",hash);
Чтобы увидеть, что вы создали!
Убедись, что ты #import <CommonCrypto/CommonHMAC.h>
тоже
Я не сравнивал следующий код с выводом функции PHP, но он работает для меня:
+(NSString *)signWithKey:(NSString *)key usingData:(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);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
return [[HMAC.description stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""];
}
Дайте мне знать, если это было полезно...
Я провожу целый день, пытаясь преобразовать сгенерированный хеш (байты) в читаемые данные. Я использовал base64, закодированный как ответ выше, и он не работал для меня вообще (кстати, вам нужен внешний.h, чтобы иметь возможность использовать кодировку base64, которая у меня была).
Так что я сделал это (что прекрасно работает без внешнего.h):
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
// Now convert to NSData structure to make it usable again
NSData *out = [NSData dataWithBytes:cHMAC length:CC_SHA256_DIGEST_LENGTH];
// description converts to hex but puts <> around it and spaces every 4 bytes
NSString *hash = [out description];
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
// hash is now a string with just the 40char hash value in it
NSLog(@"%@",hash);
Для справки, это хеширование HMac будет работать на PHP.
- (NSString *)getToken:(NSString *)queryString
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *dateString = [formatter stringFromDate:[NSDate date]];
NSDate *dateTodayUTC = [formatter dateFromString:dateString];
NSString *nowTimestamp = [NSString stringWithFormat:@"%.f", [dateTodayUTC timeIntervalSince1970]];
NSString *hashCombinations = [[NSString alloc] initWithFormat:@"%@%@%.f", queryString, public_api_key, [dateTodayUTC timeIntervalSince1970]];
const char *privateKey = [private_api_key cStringUsingEncoding:NSUTF8StringEncoding];
const char *requestData = [hashCombinations cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
//HmacSHA256
CCHmac(kCCHmacAlgSHA256, // algorithm
privateKey, strlen(privateKey), // privateKey
requestData, strlen(requestData), // requestData
cHMAC); // length
NSString *hash;
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", cHMAC[i]];
hash = output;
NSString *base64HashString = [self base64String:hash];
self.tokenLabel.text = hash;
NSLog(@"generated hash = %@", hash);
NSLog(@"base64 hash = %@", base64HashString);
NSLog(@"timestamp = %@ nsdate utc = %@", nowTimestamp, dateString);
NSLog(@"combinations %@", hashCombinations);
return [base64HashString urlencode];
}
Вы можете использовать этот метод base64.
- (NSString *)base64String:(NSString *)str
{
NSData *theData = [str dataUsingEncoding: NSASCIIStringEncoding];
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
Я думаю, что это более компактное решение:
#import <CommonCrypto/CommonCrypto.h>
...
-(NSData*)Sha256WithKey:(NSData*)key andData:(NSData*)data{
NSMutableData* result = [NSMutableData
dataWithCapacity:CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, [key bytes], [key length],
[data bytes], [data length], result.mutableBytes);
return result;
}
....