尝试调用Coinbase API端点时,出现“无效签名”错误

时间:2020-06-14 22:22:19

标签: java coinbase-api

我目前正在尝试构建一个使用Coinbase API进行交易的个人应用程序。但是,每次尝试调用需要身份验证的端点“无效签名”时,我都会遇到相同的错误。

我之所以仅在此处发布此帖子,是因为我在Internet(包括stackoverflow)中搜寻了几乎所有解决方案,但都没有成功。我的运行假设是,我使用的HmacSHA256方法不正确,但是我尝试了很多,但没有一个起作用。我做这个假设是因为我的HmacSHA256方法的参数是:

String secretKey, String timestamp, String method, String requestPath, String body

prehash字符串是时间戳+方法+ requestPath +正文,并在prehash字符串上使用密钥。

我已验证我的密钥正确(甚至创建了新的API密钥来确保这一点),并验证了时间戳是正确的,因为它不会检查标头是否不正确(通过创建错误的时间戳进行测试,该错误每次都被捕获),该方法是一个简单的“ GET”,而且我不确定我的请求路径。我正在尝试调用https://api.coinbase.com/v2/accounts,并且我假设“ / v2 / accounts”是请求路径。正文对于GET请求是可选的。

在这里创建标题:

    public static JSONObject getAccountData() {
        String url = requests.getJSONObject("wallet_data").getString("requestPath");
        String requestPath = "/v2/accounts";
        String accessKey = credentials.getJSONObject("standard").getString("key");
        String secretKey = credentials.getJSONObject("standard").getString("secret");
        String method = "GET";
        String timestamp = getEpochTime();
        String body = "";
        String header = HeaderGenerator.getHMACHeader(secretKey, timestamp, method, requestPath, body);


        Request request = new Request.Builder()
                .addHeader(CB_ACCESS_KEY, accessKey)
                .addHeader(CB_ACCESS_SIGN, header)
                .addHeader(CB_ACCESS_TIMESTAMP, timestamp)
                .addHeader(CB_VERSION, getDate())
                .addHeader("Accept", "application/json")
                .url(url)
                .build();

        String show = "";
        for(int i = 0; i < request.headers().size(); i++) {
            show += (request.headers().name(i) + ": " + request.headers().get(request.headers().name(i)));
            show+= "\n";
        }
        System.out.println(show);
        Response res;
        JSONObject par = null;
        try {
            res = APICommunicator.sendRequest(request);
            par = new JSONObject(res);
        } catch (IOException e) {
            e.printStackTrace();
            ErrorLogger.logException(e);
        }
        return par;
    }

以及HmacSHA256方法:

    public static String getHMACHeader(String secretKey, String timestamp, String method, String requestPath, String body) {
        String prehash = timestamp + method.toUpperCase() + requestPath;

        if(method.equals("POST") || method.equals("PUT")) {
            prehash += body;
        }

         byte[] secretDecoded = Base64.getDecoder().decode(secretKey);
         SecretKey keyspec = new SecretKeySpec(secretDecoded, "HmacSHA256");
         Mac sha256 = null;
        try {
            sha256 = (Mac) Mac.getInstance("HmacSHA256");
            sha256.init(keyspec);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

         return Base64.getEncoder().encodeToString(sha256.doFinal(prehash.getBytes()));
    }

我再次确保我的API密钥和秘密密钥正确无误并已启用。

1 个答案:

答案 0 :(得分:0)

找到了解决方案!

我使用的许多指南都利用了Coinbase Pro的API,该API使用Base64编码方案。在Normal Coinbase中,编码应为十六进制。

这是我更新的getHMacHeader方法:

    public static String getHMACHeader(String secretKey, String timestamp, String method, String requestPath, String body) {
        String prehash = timestamp + method.toUpperCase() + requestPath;

        if(method.equals("POST") || method.equals("PUT")) {
            prehash += body;
        }

         SecretKeySpec keyspec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
         Mac sha256 = null;
        try {
            sha256 = (Mac) Mac.getInstance("HmacSHA256");
            sha256.init(keyspec);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }

        String hash = Hex.encodeHexString((sha256.doFinal(prehash.getBytes())));

        return hash;
    }
相关问题