2016-09-03 2 views
1

Ich versuche API beschrieben here zu verwenden. Es verwendet HMAC SHA512-Autorisierung basierend auf einem geheimen Schlüssel.Abrufen von Daten aus der API mit HMAC SHA512 - Swift

Es ist ein Beispiel für die Umsetzung in 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); 
} 

Dann versuchte ich es in Swift umzusetzen:

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] 
} 

Wie Sie bemerkt haben, gibt es keine Alamofire Nutzungsdaten für das Abrufen noch, weil ich ein Problem mit dem Vorbereiten der zu sendenden Daten habe. Ich meine, ich habe etwas mit CryptoSwift vermasselt, weil ich diesen Fehler bekomme: Cannot convert value of type '[String : Any]' to expected argument type 'Array<UInt8>', wenn ich versuche, hmac Variable zu deklarieren.

Wie löst man es? Ich muss wahrscheinlich params Array zu Array<UInt8 irgendwie konvertieren, aber ich weiß nicht, wie das geht. Ich bin mir nicht sicher, ob alles auch richtig ist.

Edit: Dank Martin R, der eigentliche Code ist:

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

    let query = NSURLComponents() 
    query.queryItems = [NSURLQueryItem(name: "method", value: method) as URLQueryItem, 
         NSURLQueryItem(name: "tonce", value: String(Int(NSDate().timeIntervalSince1970))) as URLQueryItem] 

    let requestString = query.query! 
    let requestData = Array(requestString.utf8) 

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

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

    let hmacData = Data(bytes: hmac) 
    let hmacString = hmacData.base64EncodedString() 

    let headers = [ 
     "API-Key": publicKey, 
     "API-Hash": hmacString 
    ] as [String : String] 

    Alamofire.request(APIURL, withMethod: .post, parameters: params, encoding: .url, headers: headers) 
     .responseJSON { response in 
     print(response) 
    } 
} 

Leider ist nach der Funktion (getRawJSON(method: "info", paramether: "")) Aufruf, ich bin Holen eines JSON mit einem Fehler:

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

Was ist falsch mit meinem Hash?

Antwort

0

Ihr Swift Code fehlt, was

$post = http_build_query($params, "", "&"); 

tut in der PHP-Version: Erstellen Sie eine Abfrage-String aus den gegebenen Parametern. Sie können entweder "manuell" die Zeichenfolge bauen oder NSURLComponents verwenden:

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 

konvertieren Schließlich diese Zeichenfolge in eine [UInt8] Array für die HMAC Funktion:

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

Großen Dank, hat mir sehr geholfen. Jetzt bekomme ich ein Problem mit Hash, bearbeite meine Frage mit mehr Details. – kkarol

+0

@kkarol: Vergleichen Sie die Werte '$ post' und' $ sign' aus dem PHP-Code mit 'requestString' und' hmac' aus dem Swift-Code. –

+0

'requestString' ist gleich $ post, aber' $ sign' unterscheidet sich von 'hmac' und' hmacString'. 'hmacString' ist base64, während' $ sign' z. '450043310da274122369bfc0ca621e47fb0b03857746c096a944748585fcd3280744ee4633711f98bbfe3bf0c199deec329a64b723799e597304cfd683ac40e6'. Ich weiß nicht, wie man 'Array 'in das richtige Format umwandelt. – kkarol

Verwandte Themen