I’m seeing a lot of signature related quesstions lately. So I’d like to take a second to just post this example to hopefully catch some of the quesstions before they are asked.
First thing you’ll need is a functional signature method. This requires several inputs, the most important of which is your api key, not the secret key that for whatever reason seems to be a popular choice.
private String signMessage(String timestamp, String method, String path, String body) // ENCRYPTED HASH SECURITY SIGNATURE BUILDER
throws NoSuchAlgorithmException, InvalidKeyException {
String prehash = timestamp + method + path + body;
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
byte secretDecoded = Base64.getDecoder().decode(this.coinbaseAPIKey);
SecretKeySpec secret_key = new SecretKeySpec(secretDecoded, "HmacSHA256");
sha256_HMAC.init(secret_key);
return Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(prehash.getBytes()));
}
The second most important thing you need to be sure of is your request headers, both content and accept headers be to be set properly as well as the security credentials. Failure to set any of these parameters will result in an invalid signature response from the server.
String timeStamp = Instant.now().getEpochSecond() + "";
request = HttpRequest.newBuilder()
.uri(URI.create(String.join("", coinbaseProBaseURL, endpoint)))
.header("CB-ACCESS-KEY", coinbaseSecretKey)
.header("CB-ACCESS-PASSPHRASE", coinbasePassphrase)
.header("CB-ACCESS-SIGN", signMessage(timeStamp, "POST", endpoint, requestBody))
.header("CB-ACCESS-TIMESTAMP", timeStamp).header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(requestBody))
.build();