Swift调用Bittrex API时HMAC SHA512签名无效问题排查
解决Bittrex API的INVALID_SIGNATURE错误
看了你的代码和遇到的问题,这个INVALID_SIGNATURE错误主要是因为签名生成的逻辑搞反了,还有几个小细节没处理对,我帮你一步步修正:
核心错误点
- HMAC签名的参数顺序完全颠倒:Bittrex的API要求用你的
secret作为HMAC的密钥,对**完整的请求URI(包含查询参数)**进行SHA-512哈希。你现在是用URI当密钥,去哈希secret,这肯定通不过签名验证。 - 重复传递参数且编码方式错误:你既在URI里拼接了
apikey和nonce,又在parameters里传了一次,而且用了JSONEncoding.default——GET请求的参数应该只放在URL查询串里,不需要在请求体里传JSON格式的参数。 - 签名结果没有转成正确的十六进制字符串:直接把HMAC的结果转成String会得到类似
[UInt8]的描述文本,而Bittrex要求的是十六进制编码的字符串。
修正后的代码
// NONCE:确保是整数时间戳,这里逻辑没问题 let timeInterval = NSDate().timeIntervalSince1970 let nonceTime = String(Int(floor(timeInterval))) // 构建完整的请求URI(包含apikey和nonce参数) let uri = "https://bittrex.com/api/v1.1/account/getbalances?apikey=\(key)&nonce=\(nonceTime)" // 生成签名:用secret作为HMAC密钥,对URI进行SHA-512哈希 guard let hmacData = HMAC(algorithm: .sha512, key: secret).update(string: uri)?.final() else { print("Failed to generate HMAC") return } // 将HMAC结果转换成十六进制字符串(符合Bittrex的要求) let skey = hmacData.map { String(format: "%02x", $0) }.joined() // 请求头只需要apisign字段 let headers: HTTPHeaders = ["apisign": skey] // GET请求不需要额外传parameters,参数已经在URI里了 Alamofire.request(uri, method: .get, headers: headers).responseJSON { response in print("\(response)") }
额外注意事项
- 确保你的
key和secret是从Bittrex后台正确获取的,没有复制错误或者包含多余空格。 - Nonce必须是递增的,每次请求都要比上一次大,不能重复使用同一个nonce。
- 确认你的请求没有被代理或者中间件修改过URI,否则签名会不匹配。
内容的提问来源于stack exchange,提问作者iloveStackOverflow
相关产品推荐
相关产品推荐

