java - 目标相当于 base16().decode(String)

标签 java android ios objective-c hmac

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

我们已经确定问题出在 java 中的 HMAC_KEY 上, key 首先被转换为 base16 字节 []。与以下内容等效的 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 中做到这一点?

最佳答案

从你的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()))

关于java - 目标相当于 base16().decode(String),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38853390/

相关文章:

java - 通过传递字符串而不是字符串数组来解析句子斯坦福解析器

java - 在 WEB-INF 文件夹下包含 JSP 文件

iphone - 如何通过点击更改 UILabel 的 alpha?

iphone - UITextField 在 iOS 5 中导致崩溃,在 iOS 4 中工作正常

java - Openshift 将 Tomcat 7 (JBoss EWS 2.0) Cartridge 中的 java 7 更新为 8

java cxf Web服务客户端中的java.lang.VerifyError : org. bouncycaSTLe.asn1.x500.X500Name

android - Android 中的自定义蓝牙协议(protocol)支持

java - 在 ViewPager 的滑动上停止 Exoplayer

android - VectorDrawable 导致 NumberFormatException

ios - 以编程方式/手动创建 MKPlacemark/CLPlacemark