我目前正在尝试构建一个使用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密钥和秘密密钥正确无误并已启用。
答案 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;
}