You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java调用Coinbase API始终返回无效签名问题求助

Fixing Coinbase API "Invalid Signature" Error in Java

Hey there, let's break down the issues in your code that's causing the "Invalid Signature" error—there are a few key mistakes in how you're generating the signature and passing parameters:

1. Incorrect Parameter Order When Calling createSignature

Looking at your method call:

createSignature("my_secret_key", path, "GET",currTime,"")

But your method signature is createSignature(String secret, String time, String method,String uri, String body). You've swapped the order of path (uri) and time/method! This means your prehash string is using the full URL as the timestamp, which is totally wrong.

2. Using Full URL Instead of Relative URI for Signature

Coinbase requires the relative path (like /v2/user) in the prehash, not the full https://api.coinbase.com/v2/user URL. Using the full URL will mismatch what the API expects.

3. Wrong Secret Handling & Signature Algorithm

You're making two critical mistakes here:

  • You're hashing the secret with SHA256 (sha256Hex(secret)) instead of Base64-decoding it to get the raw HMAC key.
  • You're using plain SHA256 on the prehash instead of HMAC-SHA256 with the decoded secret as the key. Coinbase's signature requires HMAC, not a plain hash.

Corrected Code

Let's fix all these issues step by step.

First, the corrected createSignature method:

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public static String createSignature(String secret, String time, String method, String uri, String body) throws Exception {
    // Step 1: Base64 decode the secret to get the HMAC key
    byte[] decodedSecret = Base64.getDecoder().decode(secret);
    
    // Step 2: Create the prehash string with correct components
    String prehash = time + method.toUpperCase() + uri + body;
    
    // Step 3: Generate HMAC-SHA256 signature
    Mac hmacSha256 = Mac.getInstance("HmacSHA256");
    SecretKeySpec keySpec = new SecretKeySpec(decodedSecret, "HmacSHA256");
    hmacSha256.init(keySpec);
    byte[] signatureBytes = hmacSha256.doFinal(prehash.getBytes(StandardCharsets.UTF_8));
    
    // Step 4: Base64 encode the signature bytes
    String signature = Base64.getEncoder().encodeToString(signatureBytes);
    System.out.println("Generated Signature: " + signature);
    return signature;
}

Then, the corrected request code:

String relativeUri = "/v2/user"; // Use relative path, not full URL
String fullPath = "https://api.coinbase.com" + relativeUri;
// Use the timestamp you fetched from Coinbase's API here
String currTime = "your_epoch_timestamp_in_seconds";

HttpRequest request = HttpRequest.newBuilder()
        .uri(new URI(fullPath))
        .headers(
                "CB-ACCESS-KEY", "my_access_key",
                "CB-ACCESS-SIGN", createSignature("my_secret_key", currTime, "GET", relativeUri, ""),
                "CB-ACCESS-TIMESTAMP", currTime
        )
        .GET()
        .build();

Additional Checks

  • Double-check that your currTime is a Unix timestamp in seconds (not milliseconds). Your note says you're getting it from Coinbase's API, which is good—just confirm it's a string of digits (e.g., "1699999999").
  • For POST/PUT requests later, ensure the body parameter uses the exact JSON body sent in the request (no extra whitespace or formatting changes, as Coinbase checks for exact content matches).

内容的提问来源于stack exchange,提问作者thedevilindisguise

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:39:05