目前我们的团队正在开发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中做到这一点?
答案 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()))