obj-c和swift中的相同HMAC算法会产生不同的哈希值

时间:2014-11-01 09:53:17

标签: ios objective-c swift hmac

我有两种方法可以从字符串创建sha1哈希。使用相同的输入数据,此算法会创建不同的哈希值,但是它们应该创建相同的哈希值。

在swift中(创建617fb90f14f2eacecc333d558237bf8bb9fc85f7):

static func sha1FromMessage(message: String) -> String {

    let cKey = RestUtils.API_KEY.cStringUsingEncoding(NSASCIIStringEncoding)!
    let cData = message.cStringUsingEncoding(NSUTF8StringEncoding)!

    var cHMAC = [CUnsignedChar](count: Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), cKey, UInt(cKey.count), cData, UInt(cData.count), &cHMAC)

    let output = NSMutableString(capacity: Int(CC_SHA1_DIGEST_LENGTH))

    for byte in cHMAC {
        output.appendFormat("%02hhx", byte)
    }

    return output
}

和obj-c(创建d80b816f0b46d5211b6d9487089597e181717ea6)

+(NSString *)sha1FromMessage:(NSString *)message{

    const char *cKey  = [API_KEY cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [message cStringUsingEncoding:NSUTF8StringEncoding];

    unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];

    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    NSData *HMACData = [NSData dataWithBytes:cHMAC length:sizeof(cHMAC)];

    const unsigned char *buffer = (const unsigned char *)[HMACData bytes];
    NSMutableString *HMAC = [NSMutableString stringWithCapacity:HMACData.length * 2];

    for (int i = 0; i < HMACData.length; ++i){
        [HMAC appendFormat:@"%02hhx", buffer[i]];
    }

    return HMAC;
}

我希望swift方法返回与obj-c方法相同的哈希值。问题出在哪里?

1 个答案:

答案 0 :(得分:2)

原因是

创建了cData
let cData = message.cStringUsingEncoding(NSUTF8StringEncoding)!

包含消息字符串的终止NUL字符并计入 UInt(cData.count)也是如此。您可以使用UInt(strlen(cData))来修复此问题, 就像你的Objective-C代码一样。

但更好的解决方案是转换输入字符串 改为NSData个对象:

let cKey = RestUtils.API_KEY.dataUsingEncoding(NSASCIIStringEncoding)!
let cData = message.dataUsingEncoding(NSUTF8StringEncoding)!

var cHMAC = [CUnsignedChar](count: Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), cKey.bytes, UInt(cKey.length), cData.bytes, UInt(cData.length), &cHMAC)

通过此修改,Swift和Objective-C代码生成相同的消息摘要。