iOS使用CryptoKit生成SHA512哈希值与Android结果不一致问题咨询
iOS与Android端SHA512哈希结果不一致修复方案
核心问题1:代码存在多处变量拼写错误
当前代码中大量变量名拼写不一致,导致实际参与哈希计算的字节数组完全不符合预期,是结果异常的核心原因,错误点如下:
generateHasKey函数内:- 定义的哈希长度变量
hashSizeByts后续被错误引用为hashSizeInByts - 解码得到的盐+哈希字节数组
hashWithSaltByte后续被错误引用为hasWithSaltByte - 提取盐字节的循环边界错误引用了不存在的变量
saltBytes,实际应为saltBytesArr - 调用哈希计算函数时名称写错为
computeHas,实际定义的函数名为computeHash
- 定义的哈希长度变量
computeHash函数内:- 填充哈希结果字节的循环中,错误引用了不存在的变量
hasBytes,实际应为hashBytes - 生成最终Data时错误引用了不存在的变量
hasWithSaltBytes,实际应为hashWithSaltBytes
- 填充哈希结果字节的循环中,错误引用了不存在的变量
核心问题2:跨端规则未对齐
拼写问题修复后如果仍存在不一致,需要确认两端以下规则完全对齐:
- 传入的
jsonString完全一致:必须保证两端的json字符串空格、换行、键值顺序、特殊字符转义规则完全相同,即使单个字符差异也会导致哈希结果完全不同 - 字节拼接顺序完全一致:当前代码的逻辑是「json字符串UTF8字节 + 盐字节」做SHA512哈希,再把「哈希结果字节 + 盐字节」拼接后做Base64编码,需要确认Android侧的拼接顺序完全相同
- Base64编码规则一致:两端都要使用无换行、标准补位的Base64编码规则,iOS默认的
base64EncodedString()符合要求,Android侧不要使用带换行的编码选项
修复后的完整代码
import CryptoKit extension Digest { var bytes: [UInt8] { Array(makeIterator()) } var data: Data { Data(bytes) } } func generateHashKey(jsonString: String, hashValue: String) -> Bool { guard let data = Data(base64Encoded: hashValue) else { return false } let hashWithSaltByte: [UInt8] = Array(data) let hashSizeBytes: Int = 512 / 8 guard hashWithSaltByte.count >= hashSizeBytes else { return false } let saltBytesArr: [UInt8] = Array(hashWithSaltByte[hashSizeBytes..<hashWithSaltByte.count]) let expectedHashString = computeHash(jsonString: jsonString, saltBytes: saltBytesArr) if expectedHashString == hashValue { print("Hash value match..") return true } else { print("Hash value did not match..") return false } } func computeHash(jsonString: String, saltBytes: [UInt8]) -> String { let jsonStringBytes: [UInt8] = Array(jsonString.utf8) var jsonStringWithSaltBytes: [UInt8] = Array(repeating: 0, count: (jsonStringBytes.count + saltBytes.count)) for index in 0..<jsonStringBytes.count { jsonStringWithSaltBytes[index] = jsonStringBytes[index] } for index in 0..<saltBytes.count { jsonStringWithSaltBytes[jsonStringBytes.count + index] = saltBytes[index] } let digest = SHA512.hash(data: jsonStringWithSaltBytes) let hashBytes = digest.bytes var hashWithSaltBytes: [UInt8] = Array(repeating: 0, count: (hashBytes.count + saltBytes.count)) for index in 0..<hashBytes.count { hashWithSaltBytes[index] = hashBytes[index] } for index in 0..<saltBytes.count { hashWithSaltBytes[hashBytes.count + index] = saltBytes[index] } let finalSaltData = Data(hashWithSaltBytes) let finalHashString = finalSaltData.base64EncodedString() return finalHashString }
内容的提问来源于stack exchange,提问作者Pratik Parmar
相关产品推荐
相关产品推荐

