使用HMAC SHA512-Swift从API获取数据

使用HMAC SHA512-Swift从API获取数据,swift,hmac,sha512,Swift,Hmac,Sha512,我正在尝试使用描述的API。它使用基于密钥的HMAC SHA512授权 有一个PHP实现的示例: function bitmarket_api($method, $params = array()) { $key = "klucz_jawny"; $secret = "klucz_tajny"; $params["method"] = $method; $params["tonce"] = time(); $post = http_build_query($params,

我正在尝试使用描述的API。它使用基于密钥的HMAC SHA512授权

有一个PHP实现的示例:

function bitmarket_api($method, $params = array())
{
  $key = "klucz_jawny";
  $secret = "klucz_tajny";

  $params["method"] = $method;
  $params["tonce"] = time();

  $post = http_build_query($params, "", "&");
  $sign = hash_hmac("sha512", $post, $secret);
  $headers = array(
      "API-Key: " . $key,
      "API-Hash: " . $sign,
  );

  $curl = curl_init();
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_URL, "https://www.bitmarket.pl/api2/");
  curl_setopt($curl, CURLOPT_POST, true);
  curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  $ret = curl_exec($curl);

  return json_decode($ret);
}
然后我尝试用Swift实现它:

import Alamofire
import CryptoSwift

func getRawJSON(method: String, params: [String]) -> String {
    let publicKey = "publicKeyHere"
    let secretKey = "secretKeyHere"
    let APIURL = "https://www.bitmarket.pl/api2/"

    var params = [
        "method": method,
        "tonce:": NSDate().timeIntervalSince1970
        ] as [String : Any]

    let hmac: Array<UInt8> = try! HMAC(key: secretKey.utf8.map({$0}), variant: .sha512).authenticate(params)

    var headers = [
        "API-Key": publicKey,
        "API-Hash": hmac
    ] as [String : Any]
}
不幸的是,在调用函数(
getRawJSON(方法:“info”,参数:)
)后,我获取一个JSON时出错:

{
error = 502;
errorMsg = "Invalid message hash";
time = 1472910139;
}

我的哈希怎么了?

您的Swift代码缺少什么

$post = http_build_query($params, "", "&");
在PHP版本中执行:根据给定参数创建查询字符串。 您可以“手动”生成该字符串,也可以使用
NSURLComponents

let comps = NSURLComponents()
comps.queryItems = [ NSURLQueryItem(name: "method",
                                    value: "YOUR_METHOD"),
                     NSURLQueryItem(name: "tonce",
                                    value: String(Int(NSDate().timeIntervalSince1970))) ]
let requestString = comps.query!
print(requestString) // method=YOUR_METHOD&tonce=1472893376
最后,将此字符串转换为HMAC的
[UInt8]
数组 功能:

let requestData = Array(requestString.utf8)
print(requestData) // [109, 101, 116, ..., 54]

你的Swift密码丢失了什么

$post = http_build_query($params, "", "&");
在PHP版本中执行:根据给定参数创建查询字符串。 您可以“手动”生成该字符串,也可以使用
NSURLComponents

let comps = NSURLComponents()
comps.queryItems = [ NSURLQueryItem(name: "method",
                                    value: "YOUR_METHOD"),
                     NSURLQueryItem(name: "tonce",
                                    value: String(Int(NSDate().timeIntervalSince1970))) ]
let requestString = comps.query!
print(requestString) // method=YOUR_METHOD&tonce=1472893376
最后,将此字符串转换为HMAC的
[UInt8]
数组 功能:

let requestData = Array(requestString.utf8)
print(requestData) // [109, 101, 116, ..., 54]

非常感谢,帮了很多忙。现在我遇到了哈希问题,编辑了我的问题并提供了更多细节。@kkarol:将PHP代码中的
$post
$sign
值与Swift代码中的
requestString
hmac
进行比较。
requestString
等于
$post
,但是,
$sign
不同于
hmac
hmacString
hmacString
是base64,而
$sign
包含例如
450043310DA27412239BFC0CA621E47FB0B03857746C096A944748585FCD3280744EE4633711F98BBFE3BF0C199DEEC329A64B723799E597304CFD683AC40E6
。不知道如何将数组转换成正确的格式。@kkarol:您必须将数据转换成十六进制字符串,而不是Base64编码的字符串。例如,非常感谢,帮了很多忙。现在我遇到了哈希问题,编辑了我的问题并提供了更多细节。@kkarol:将PHP代码中的
$post
$sign
值与Swift代码中的
requestString
hmac
进行比较。
requestString
等于
$post
,但是,
$sign
不同于
hmac
hmacString
hmacString
是base64,而
$sign
包含例如
450043310DA27412239BFC0CA621E47FB0B03857746C096A944748585FCD3280744EE4633711F98BBFE3BF0C199DEEC329A64B723799E597304CFD683AC40E6
。不知道如何将数组转换成正确的格式。@kkarol:您必须将数据转换成十六进制字符串,而不是Base64编码的字符串。例如,见。