2

私はパートナーと協力していますが、C#とObjective-Cで、それぞれの言語で同じツールと思われるものを使用して同じハッシュを生成することはできません。C#では、私はこれを行っています:

byte[] noncebytes=new byte[32];
//We seed the hash generator with a new 32 position array.  Each position is 0.
//In prod code this would be random, but for now it's all 0s.
HMACSHA256 hmac256 = new HMACSHA256(noncebytes);          
string plaintext = "hello";
string UTFString = Convert.ToBase64String(
    System.Text.Encoding.UTF8.GetBytes(plaintext));  
string HashString = Convert.ToBase64String(
    hmac256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(plaintext)));  //Convert that hash to a string.

これにより、次のbase64stringハッシュが生成されます。

Q1KybjP + DXaaiSKmuikAQQnwFojiasyebLNH5aWvxNo =

これを行うための同等のObjective-Cコードは何ですか?一致するデータに対して一致するハッシュを生成できるようにするには、クライアントとサーバーが必要です。

現在使用しているObjective-Cコードは次のとおりです。

   ...

    NSData *zeroNumber = [self zeroDataWithBytes:32]; //empty byte array
    NSString *nonceTest = [zeroNumber base64String];  // using MF_Base64Additions.h here
    NSData *hashTest = [self hmacForKeyAndData:nonceTest withData:@"hello"]; //creating hash
    NSString *hashTestText = [hashTest base64String]; 
    NSLog(@"hello hash is %@",  hashTestText);

...

    //functions for zeroing out the byte.  I'm sure there's a better way

    - (NSData *)zeroDataWithBytes: (NSUInteger)length {
   NSMutableData *mutableData = [NSMutableData dataWithCapacity: length];
    for (unsigned int i = 0; i < length; i++) {
       NSInteger bits = 0;
      [mutableData appendBytes: (void *) &bits length: 1];
    } return mutableData;
}

//hash function

-(NSData *) hmacForKeyAndData:(NSString *)key withData:(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);
    return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
4

2 に答える 2

1

更新

GitHubには、必要なすべてを達成しているように見える非常に優れたプロジェクトに加えて、暗号化に関連するオプションがたくさんあります。ユニットテストが含まれます。


NSData *hmacForKeyAndData(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);
    return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}

出典

以上で、輸入があると思います<CommonCrypto/CommonHMAC.h>。Base64にエンコードするための次のステップ:

+ (NSString *)Base64Encode:(NSData *)data
{
    //Point to start of the data and set buffer sizes
    int inLength = [data length];
    int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0);
    const char *inputBuffer = [data bytes];
    char *outputBuffer = malloc(outLength);
    outputBuffer[outLength] = 0;

    //64 digit code
    static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    //start the count
    int cycle = 0;
    int inpos = 0;
    int outpos = 0;
    char temp;

    //Pad the last to bytes, the outbuffer must always be a multiple of 4
    outputBuffer[outLength-1] = '=';
    outputBuffer[outLength-2] = '=';

    /* http://en.wikipedia.org/wiki/Base64
     Text content   M           a           n
     ASCII          77          97          110
     8 Bit pattern  01001101    01100001    01101110

     6 Bit pattern  010011  010110  000101  101110
     Index          19      22      5       46
     Base64-encoded T       W       F       u
     */


    while (inpos < inLength){
        switch (cycle) {
            case 0:
                outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2];
                cycle = 1;
                break;
            case 1:
                temp = (inputBuffer[inpos++]&0x03)<<4;
                outputBuffer[outpos] = Encode[temp];
                cycle = 2;
                break;
            case 2:
                outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4];
                temp = (inputBuffer[inpos++]&0x0F)<<2;
                outputBuffer[outpos] = Encode[temp];
                cycle = 3;                  
                break;
            case 3:
                outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6];
                cycle = 4;
                break;
            case 4:
                outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f];
                cycle = 0;
                break;                          
            default:
                cycle = 0;
                break;
        }
    }
    NSString *pictemp = [NSString stringWithUTF8String:outputBuffer];
    free(outputBuffer); 
    return pictemp;
}
于 2013-02-21T16:24:12.627 に答える
1

質問のobjective-c部分のコードの2行目に注意してください。

NSString *nonceTest = [zeroNumber base64String]; 

しかし、それはこれでなければなりません:

NSString *nonceTest = [[NSString alloc] initWithData:zeroNumber encoding:NSASCIIStringEncoding];

これは、hmacのシーイングに必要がなかったときに、文字列をbase64に変換する場合でした。

両方のプラットフォームのハッシュとして、Q1KybjP +DXaaiSKmuikAQQnwFojiasyebLNH5aWvxNo=を取得します。

于 2013-03-08T06:13:09.730 に答える