【问题标题】:Generating SHA256 in iphone/Objective C ...?在 iphone/Objective C 中生成 SHA256 ...?
【发布时间】:2011-01-17 08:59:04
【问题描述】:

如何在 iphone/objective c 中创建字符串的 SHA256...

Sha256 in Objective-C for iPhone

我读过这个..但我无法理解这个..

我想创建类似于php函数的输出如下:-

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

其中哈希参数是参数数组...

你能把它写成一个接受输入字符串的方法吗?

NSData 或 NSString 方法的输出是什么??

我必须用这个创建一个请求..??

所以在请求对象中..

[theRequest setHTTPBody:requestBody];

requestBody 的类型应该是什么??

【问题讨论】:

标签: iphone sha256


【解决方案1】:

我不确定我是否完全理解您的问题,但如果您希望创建一个散列字符串,您可以将参数作为参数传递给散列函数。

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

【讨论】:

  • 这是 base64 编码的。如果不需要,可以省略 base64 编码。
  • 那我怎样才能把hmac转换成nsstring类型呢?
  • 我也对该解决方案感兴趣,base64Encoding 我想这是一个未记录的功能,结果无论如何都不好。我正在尝试,但也不好: NSString *str = [[NSString alloc] initWithData:HMAC encoding:NSASCIIStringEncoding];
  • 效果很好。我添加了 ios7 > bases64 编码,例如NSString *hash = [HMAC base64EncodedStringWithOptions:0]; 一切顺利。谢谢@TALLBOY
【解决方案2】:

我没有将以下代码与 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:@""];
}

如果有帮助请告诉我...

【讨论】:

    【解决方案3】:

    我花了一天的时间,试图将生成的哈希(字节)转换为可读数据。我使用了 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);
    

    【讨论】:

      【解决方案4】:

      作为参考,此 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];
      }
      

      【讨论】:

        【解决方案5】:

        我认为这是更紧凑的解决方案:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-17
          • 1970-01-01
          相关资源
          最近更新 更多