Coinbase API Subscription Channel Authentication Failure Issue

Post Content:

Hello everyone,

I’m trying to subscribe to a websocket channel using Coinbase’s API, but I keep encountering an authentication failure. I’ve generated a signature and included it in the request as per the documentation and example codes, yet I’m still unable to subscribe successfully.

Here’s my subscription request JSON:

jsonCopy code

{
  "type": "subscribe",
  "product_ids": ["ETH-USD", "BTC-USD"],
  "channel": "market_trades",
  "signature": "<my generated signature>",
  "api_key": "<my API key>",
  "timestamp": "<my generated timestamp>"
}

Here’s the Java method I’m using to generate the signature:

javaCopy code

public static String generateSignature(String secretKey, long timestamp, String channel, String[] productIds) {
    String message = timestamp + channel + String.join(",", productIds);
    String signature = "";

    try {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
        sha256_HMAC.init(secretKeySpec);

        byte[] hash = sha256_HMAC.doFinal(message.getBytes(StandardCharsets.UTF_8));
        signature = Base64.getEncoder().encodeToString(hash);
    } catch (Exception e) {
        System.out.println("Error generating HMAC: " + e.getMessage());
    }

    return signature;
}

The keys and channel name I’m using are all retrieved from my Coinbase account settings. I’ve checked this information, and it’s all correct.

Each time I try to subscribe, I receive this error message: {"type":"error","message":"authentication failure"}. I’m unsure of what I’m doing wrong since I’ve been generating and inserting the signature as directed by the documentation.

If anyone knows where I might be going wrong, or has any solutions, I would greatly appreciate it.

Thanks for your help!

In Advanced Trade you don’t need to encode signature in base64.

I appreciate the help provided earlier, especially the clarification regarding not encoding the signature in Base64. However, after implementing this change and also ensuring that I am correctly converting the hash to hexadecimal, I am still encountering the “Authentication Failure” issue.

Here is my updated Java code:

javaCopy code

public static String generateSignature(String secretKey, long timestamp, String channel, String[] productIds) {
    // Joining productIds array into a comma-separated string
    String products = String.join(",", productIds);

    // Creating string to be signed
    String message = timestamp + channel + products;

    String signature = "";
    try {
        // Generating signature using HmacSHA256
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
        sha256_HMAC.init(secretKeySpec);

        byte[] hash = sha256_HMAC.doFinal(message.getBytes(StandardCharsets.UTF_8));

        // Converting hash value to hex representation
        StringBuilder hexString = new StringBuilder();
        for (int i = 0; i < hash.length; i++) {
            String hex = Integer.toHexString(0xff & hash[i]);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }

        signature = hexString.toString();
    } catch (Exception e) {
        System.out.println("Error generating HMAC: " + e.getMessage());
    }

    return signature;
}

The above method generates a hex string as the signature. However, this modification did not solve the issue. I am still facing the “authentication failure” error message.

Are there any other points I might be missing or is there anything else I need to check or modify?

Don’t know…

Maybe try to use both getBytes without utf8 and/or both with it? No idea if that changes anything.

Also try to search this forum, many have had similar problems, you might find answer in other topics.