2011-01-17 13 views
11

Como crear un SHA256 de una cadena en iPhone/c objetivo ...Generando SHA256 en iphone/Objective C ...?

Sha256 in Objective-C for iPhone

He leído this..but que no soy capaz de entender esto ..

quiero crear una salida similar a php funcation de la siguiente manera: -

$hash = hash_hmac("sha256", implode(';', $hash_parameters), $api_key); 

donde los parámetros hash es la matriz de argumentos ...

¿Puedes escribir esto como un método que tomará la cadena de entrada ...?

¿Y cuál será la salida del método NSData o NSString .. ??

Tengo que crear una solicitud con este .. ??

Así en el objeto solicitud ..

[theRequest setHTTPBody:requestBody]; 

lo que debería ser el tipo de requestBody ??

+0

Esta fue una respuesta clara aquí-> http://stackoverflow.com/questions/3709204/sha256-in-objective-c-for- iphone/11426583 # 11426583 – Jagadeeshwar

Respuesta

17

No estoy seguro de entender completamente sus preguntas, pero si está buscando crear una cadena hash, PUEDE pasar sus parámetros como argumentos a una función hash.

-(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]; 

} 

Esto le dará un NSString de hash que puede usar para realizar sus solicitudes. NSLog(@"%@",hash); ¡Para ver lo que has generado!

Asegúrese de que #import <CommonCrypto/CommonHMAC.h> demasiado

+0

Intenté esto, pero la salida es diferente de la función php – Maysam

+0

Esto está codificado en base64.Puede omitir la codificación base64 si no la necesita. – TALLBOY

+0

¿cómo puedo convertir el hmac a nsstring type? – Maysam

2

paso un día agujero, tratando de convertir el hash generado (bytes) en datos legibles. Utilicé el base64 codificado como la respuesta anterior y no funcionó en absoluto para mí (es decir, necesitas una .h externa para poder usar la codificación base64, que tenía).

Así que lo que hice estuvo presente (que funciona perfectamente sin un .h externo):

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); 
3

que no se puede comparar el código siguiente a la salida de la función PHP pero funciona para mí:

+(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:@""]; 
} 

Avisadme si era útil ...

1

Para una referencia de este hash HMAC trabajará en 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]; 
} 

Puede utilizar este método 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[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/="; 

    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]; 
} 
0

creo que es más solución compacta:

#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; 
} 
....