【问题标题】:Equivalent Hashing in C# and Objective-C using HMAC256使用 HMAC256 在 C# 和 Objective-C 中进行等效散列
【发布时间】:2013-03-08 14:14:19
【问题描述】:

我正在与合作伙伴合作,但我们无法让 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)];
}

【问题讨论】:

    标签: objective-c hash hmac


    【解决方案1】:

    更新

    有一个相当不错的project on 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)];
    }
    

    (Source)

    有了以上内容,我想你会导入&lt;CommonCrypto/CommonHMAC.h&gt;。编码为 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;
    }
    

    【讨论】:

    • 我无权访问 obj-c 代码库。如果您使用您提供的代码并对字符串 "hello" 进行哈希处理,您会得到与我相同的哈希值吗?即:Q1KybjP+DXaaiSKmuikAQQnwFojiasyebLNH5aWvxNo=
    • @GenghisJahn 很抱歉,但我不能。我的工作区右侧没有可供我使用的 SHA 方法。
    • @GenghisJahn 在 GitHub 上添加了一个有前途的项目的链接。
    • 谢谢,我们会检查一下。我正在尝试获取我们的 obj-c 代码,以便我也可以在这里发布。
    【解决方案2】:

    注意问题的objective-c部分的第二行代码。

    NSString *nonceTest = [zeroNumber base64String]; 
    

    但应该是这样的:

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

    当我们不需要hmac播种时,将字符串转换为base64。

    我们现在得到:Q1KybjP+DXaaiSKmuikAQQnwFojiasyebLNH5aWvxNo= 作为两个平台上的哈希值。

    【讨论】:

      猜你喜欢
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多