首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Base64和HMAC SHA-256在Java中的编解码

Base64和HMAC SHA-256在Java中的编解码
EN

Stack Overflow用户
提问于 2017-09-18 18:55:41
回答 1查看 3.9K关注 0票数 0

我正在努力获得GDAX的平衡,但我认为我无法正确地处理Java中的编码/解码。API引用在这里:https://docs.gdax.com/#authentication,我试图做的部分是在Accounts ->列表帐户下面(只需要从上面的链接向下滚动一点点)来获得平衡。

这是我的密码。我似乎无法让它发挥作用,尽管我已经做了很多搜索谷歌和这里。我一直从服务器得到一个400错误,意思是“糟糕的请求-无效请求格式”。

代码语言:javascript
复制
    // 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()中的代码,以防出现问题。我知道它在没有参数的情况下工作,但我不知道它是否正确地使用这些参数,因为我无法让它工作。

代码语言:javascript
复制
    // 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;
    }
EN

回答 1

Stack Overflow用户

发布于 2018-02-15 13:19:27

我让这个在本地工作。看来你在双重编码你的签名。

创建签名的步骤如下:

  1. 创建形成签名基础的初始字符串。
  2. 解码您的秘密以获得一个KeySpec (新的SecretKeySpec())
  3. 在HMAC中使用keyspec (sha256Hmac.init())
  4. 使用秘密对请求签名(sha256Hmac.doFinal())进行编码
  5. base64对步骤4的结果进行编码。

您在上述代码段中所犯的唯一错误是,然后base64在您的标题中再次对其进行编码。

HTH

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46286341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档