11

iPhone /ObjectiveCで文字列のSHA256を作成する方法...

iPhone用Objective-CのSha256

私はこれを読みました。しかし、私はこれを理解することができません。

次のようにphp関数に似た出力を作成したい:-

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

ここで、ハッシュパラメータは引数の配列です。

これを入力文字列を受け取るメソッドとして記述できますか...?

そして、メソッドNSDataまたはNSString ..??の出力はどうなりますか?

これでリクエストを作成する必要があります..??

したがって、リクエストオブジェクトで。

[theRequest setHTTPBody:requestBody];

requestBodyのタイプはどうあるべきですか?

4

5 に答える 5

17

質問を完全に理解できるかどうかはわかりませんが、ハッシュ文字列を作成する場合は、パラメーターをハッシュ関数の引数として渡すことができます。

-(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>も確認してください

于 2011-01-26T17:01:58.163 に答える
3

次のコードを 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:@""];
}

それが役に立ったかどうか教えてください...

于 2013-01-10T05:47:13.597 に答える
2

生成されたハッシュ (バイト) を読み取り可能なデータに変換しようとして、丸一日過ごしました。上記の回答のようにエンコードされたbase64を使用しましたが、まったく機能しませんでした(ところで、base64エンコーディングを使用できるようにするには外部.hが必要です)。

だから私がしたことはこれでした(これは外部.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);
于 2011-10-12T09:13:25.993 に答える
1

参考までに、この 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];
}
于 2013-05-27T17:18:12.340 に答える