2017-09-18 21 views
0

GDAXのバランスを取ろうとしていますが、Javaでエンコーディング/デコードを正しく処理できないと思います。 APIリファレンスはhttps://docs.gdax.com/#authenticationです。私がしようとしている部分は、アカウント - >アカウント一覧(上記のリンクから少し下にスクロールしてください)の下にあります。JavaのBase64とHMAC SHA-256エンコーディング/デコード

ここに私のコードがあります。私はGoogleとここでどれくらいの検索をしても機能しないようです。私はサーバーから400エラーを取得し続けています。つまり、「Bad Request - 無効な要求形式」です。

// Decode the secret key 
    byte[] decodedSecret; 
    try 
    { 
     decodedSecret = Base64.decode(SECRET_KEY); 
    } 
    catch (Base64DecodingException ex) 
    { 
     System.out.println("Failed to decode secret key."); 
     return null; 
    } 

    // Make the header parameters 
    long timestamp = (new GregorianCalendar()).getTimeInMillis()/1000; 
    String preSign = "" + timestamp + "GET" + BASE_URL + "/accounts"; 

    byte[] encodedhash; 
    try 
    { 
     Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); 
     try 
     { 
      sha256_HMAC.init(new SecretKeySpec(decodedSecret, "HmacSHA256")); 
     } 
     catch (InvalidKeyException ex) 
     { 
      System.out.println("Failed due to invalid key exception."); 
      System.out.println(ex.getMessage()); 
      return null; 
     } 
     encodedhash = sha256_HMAC.doFinal(preSign.getBytes()); 
    } 
    catch (NoSuchAlgorithmException ex) 
    { 
     System.out.println("Failed to make SHA-256 encode because of no such algorithm."); 
     return null; 
    } 

    HashMap<String, String> parameters = new HashMap<>(); 
    parameters.put("CB-ACCESS-KEY", API_KEY); 
    parameters.put("CB-ACCESS-SIGN", Base64.encode(encodedhash)); 
    parameters.put("CB-ACCESS-TIMESTAMP", "" + timestamp); 
    parameters.put("CB-ACCESS-PASSPHRASE", PASSPHRASE); 

    // Send the request 
    String response = sendGet(BASE_URL + "/accounts", parameters); 

ここには問題がある場合のために、私もsendGet()の内部にあるコードがあります。私はそれがパラメータなしで動作することを知っているが、私はそれが正常に動作するようになることができないので、パラメータを使用するかどうかわからない。

// Set up the connection 
    URL url = null; 
    try 
    { 
     url = new URL(urlStr); 
    } 
    catch (MalformedURLException ex) 
    { 
     return null; 
    } 
    HttpURLConnection con; 
    try 
    { 
     con = (HttpURLConnection) url.openConnection(); 
    } 
    catch (IOException ex) 
    { 
     System.out.println("Returning null because of failure to open connection."); 
     return null; 
    } 
    try 
    { 
     con.setRequestMethod("GET"); 
    } 
    catch (ProtocolException ex) {} 
    if (parameters != null) // if there are parameters to add to the connection 
    { 
     for (Map.Entry<String, String> pair : parameters.entrySet()) // for each pair in parameters 
     { 
      try 
      { 
       con.addRequestProperty(pair.getKey(), pair.getValue()); 
      } 
      catch (Exception ex) 
      { 
       System.out.println("Failed to add " + pair.getKey() + "."); 
      } 
     } 
    } 

    // Get the response 
    int responseCode; 
    try 
    { 
     responseCode = con.getResponseCode(); 

     BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); 
     StringBuilder responseBldr = new StringBuilder(); 
     String line; 
     while ((line = in.readLine()) != null) // while we have read another line 
     { 
      responseBldr.append(line); 
     } 
     in.close(); 
     return responseBldr.toString(); 
    } 
    catch (IOException ex) 
    { 
     System.out.println("Returning null from network IOException."); 
     System.out.println(ex.getMessage()); 
     return null; 
    } 
+0

Content-typeヘッダーは設定していますか? – algrid

+0

私はそれを設定していませんでした。有難うございます。しかし、それはまだ私に応答400を与えている。これは私がcontent-typeを追加したものです:con.addRequestProperty( "Content-type"、contentType); – cmasupra

+0

また、 'preSign'はおそらく' BASE_URL'を含んではいけません。 – algrid

答えて

0

これはローカルで動作しています。あなたの署名を二重にエンコードしているようです。

署名を作成するための手順

は、次のとおりです。

  1. がKeySpecを得るためにあなたの秘密を解読
  2. 署名の基本となる初期文字列を作成する(新しいSecretKeySpec())のinit
  3. あなたkeyspec(sha256Hmac.init())を用いてHMAC
  4. 要求署名(sha256Hmac.doFinal())を符号化するために秘密を使用
  5. BASE64は、ステップ4
  6. の結果をコード

上記のスニペットで行った唯一のエラーは、ヘッダーに再度base64エンコードすることです。

HTH

関連する問題