Objective Equivelent to base16()。decode(String)

时间:2016-08-09 14:21:22

标签: java android ios objective-c hmac

目前我们的团队正在开发HMAC密钥,但iOS和Android上的结果不同。 Java部分工作正常,但iOS部分似乎无法正常工作。

我们已经确定问题在于java中的HMAC_KEY,键首先被转换为base16 byte []。什么是Objective-C等于以下内容?

        byte[] hmacKey = BaseEncoding.base16().decode(HMAC_KEY);
        SecretKeySpec signingKey = new SecretKeySpec(hmacKey, HMAC_SHA256_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
        mac.init(signingKey);
        byte[] rawHmac = mac.doFinal(data.getBytes(C_UTF8));



        return BaseEncoding.base64().encode(rawHmac);
在ios中,我们有以下内容:

NSData *saltData = [salt dataUsingEncoding:NSUTF8StringEncoding];
NSData *paramData = [signingData dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData* hash = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH ];
CCHmac(kCCHmacAlgSHA256, saltData.bytes, saltData.length, paramData.bytes, paramData.length, hash.mutableBytes);
NSString *base64Hash = [hash base64Encoding];

问题在于BaseEncoding.base16().decode(HMAC_KEY)部分我们如何在Objective-C中做到这一点?

1 个答案:

答案 0 :(得分:0)

从Java代码中,您需要先将HMAC_KEY(HexDecimalString)转换为NSData,然后才能进行HMAC_SHA256计算。这是我的Swift解决方案

public extension String {

    func sha256(key: NSData) -> String {
        let inputData: NSData = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
        let keyData = UnsafePointer<UInt8>(key.bytes)

        let algorithm = HMACAlgorithm.SHA256
        let digestLen = algorithm.digestLength()
        let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)

        CCHmac(algorithm.toCCHmacAlgorithm(), keyData, key.length, inputData.bytes, Int(inputData.length), result)
        let data = NSData(bytes: result, length: digestLen)
        result.destroy()
        return data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
    }

    func dataFromHexadecimalString() -> NSData? {
        let data = NSMutableData(capacity: characters.count / 2)

        let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .CaseInsensitive)
        regex.enumerateMatchesInString(self, options: [], range: NSMakeRange(0, characters.count)) { match, flags, stop in
            let byteString = (self as NSString).substringWithRange(match!.range)
            var num = UInt8(byteString, radix: 16)
            data?.appendBytes(&num, length: 1)
        }

        return data
    }
}

enum HMACAlgorithm {
    case MD5, SHA1, SHA224, SHA256, SHA384, SHA512

    func toCCHmacAlgorithm() -> CCHmacAlgorithm {
        var result: Int = 0
        switch self {
        case .MD5:
            result = kCCHmacAlgMD5
        case .SHA1:
            result = kCCHmacAlgSHA1
        case .SHA224:
            result = kCCHmacAlgSHA224
        case .SHA256:
            result = kCCHmacAlgSHA256
        case .SHA384:
            result = kCCHmacAlgSHA384
        case .SHA512:
            result = kCCHmacAlgSHA512
        }
        return CCHmacAlgorithm(result)
    }

    func digestLength() -> Int {
        var result: CInt = 0
        switch self {
        case .MD5:
            result = CC_MD5_DIGEST_LENGTH
        case .SHA1:
            result = CC_SHA1_DIGEST_LENGTH
        case .SHA224:
            result = CC_SHA224_DIGEST_LENGTH
        case .SHA256:
            result = CC_SHA256_DIGEST_LENGTH
        case .SHA384:
            result = CC_SHA384_DIGEST_LENGTH
        case .SHA512:
            result = CC_SHA512_DIGEST_LENGTH
        }
        return Int(result)
    }
}

您可以像这样简单地获取base64Hash并验证结果:

print(dataString.sha256(HMAC_KEY.dataFromHexadecimalString()))