【发布时间】:2020-06-14 22:22:19
【问题描述】:
我目前正在尝试构建一个使用 Coinbase API 为我进行交易的个人应用程序。但是,每次尝试调用需要身份验证的端点时,我都会遇到相同的错误,“签名无效”。
我只是在这里发布这篇文章,因为我已经搜索了互联网(包括 stackoverflow),尝试了几乎所有解决方案,但没有一个有效。我的运行假设是我使用的 HmacSHA256 方法不正确,但我尝试了很多,但没有一个工作。我做出这个假设是因为我的 HmacSHA256 方法的参数是:
String secretKey, String timestamp, String method, String requestPath, String body
prehash 字符串是时间戳 + 方法 + requestPath + body 并使用 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 密钥和秘密密钥正确且已启用。
【问题讨论】:
标签: java coinbase-api