Coinbase Pro API - invalid signature

This is edited from original post:

From the docs:

Signing a Message The CB-ACCESS-SIGN header is generated by creating a sha256 HMAC using the base64-decoded secret key on the prehash string timestamp + method + requestPath + body (where + represents string concatenation) and base64-encode the output. The timestamp value is the same as the CB-ACCESS-TIMESTAMP header.

Here is information from a key I deleted. This is from Coinbase Pro Sandbox:

publicKey:

06057d5b5e03d0f8587a248330402b21 

passPhrase:

gcgs6k6rp0f 

secretKey: EFAToD5heo66GIgZlT2TIZzJf8TYlmxyeRxRYDHTBv3lTt9XN6uaNS0RNAy0os/caR47x6EiPDOV3Ik+YzrfEA==

I'm using angular, specifically the node.js crypto-js library:

private generateSignaturePro(timestamp: string, method: string, resourceUrl: string, requestBody: string): string { var prehash: string = timestamp + method + resourceUrl + requestBody; var key = (Buffer.from(this.secretKey, 'base64')).toString(); return crypto.enc.Base64.stringify(crypto.HmacSHA256(prehash, key)); } 

Server time is Time: 2019-05-20T19:01:38.711Z Epoch: 1558378898.711 (from /time endpoint)

here is my request and the server response:

Request:

Request URL: Request Method: GET Status Code: 400 Remote Address: 104.16.161.226:443 Referrer Policy: no-referrer-when-downgrade 

Request Headers:

Provisional headers are shown Accept: application/json, text/plain, */* CB-ACCESS-KEY: 06057d5b5e03d0f8587a248330402b21 CB-ACCESS-PASSPHRASE: gcgs6k6rp0f CB-ACCESS-SIGN: 0cc2BnQYdUhLucXSPwMTjpHjJ32G3RXSH44rSsEopvjAtY90uRCMVy6xUrzg/A/aRJBLqx390fcZc7lmJeP++g== CB-ACCESS-TIMESTAMP: 1558378899 Referer: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36 

Response Headers:

access-control-allow-headers: Content-Type, Accept, cb-session, cb-fp access-control-allow-methods: GET,POST,DELETE,PUT access-control-allow-origin: * access-control-expose-headers: cb-before, cb-after, cb-gdpr access-control-max-age: 7200 cache-control: no-store cf-cache-status: MISS cf-ray: 4da08f74ba97cf68-IAD content-length: 31 content-type: application/json; charset=utf-8 date: Mon, 20 May 2019 19:01:38 GMT etag: W/"1f-4RjKVp8I05+xcnQ5/G16yRoMSKU" expect-ct: max-age=604800, report-uri="" server: cloudflare status: 400 strict-transport-security: max-age=15552000; includeSubDomains vary: Accept-Encoding x-content-type-options: nosniff x-dns-prefetch-control: off x-download-options: noopen x-frame-options: SAMEORIGIN x-xss-protection: 1; mode=block 

Response:

{"message":"invalid signature"} 

What am I doing wrong?

EDIT: Changed method to the SHA 256 version. Still doesn't work.

3 Answers

I ran into same issue and my code was same as yours basically. I changed to the following (c#) and it finally worked. Weird thing is coinbase pro is only exchange i have had issues with so far with the signature. In any case here is the code that worked for me. Hope this helps. Would have saved me hours

public string ComputeSignature( HttpMethod httpMethod, string secret, double timestamp, string requestUri, string contentBody = "") { var convertedString = System.Convert.FromBase64String(secret); var prehash = timestamp.ToString("F0", CultureInfo.InvariantCulture) + httpMethod.ToString().ToUpper() + requestUri + contentBody; return HashString(prehash, convertedString); } private string HashString(string str, byte[] secret) { var bytes = Encoding.UTF8.GetBytes(str); using (var hmaccsha = new HMACSHA256(secret)) { return System.Convert.ToBase64String(hmaccsha.ComputeHash(bytes)); } } 
1

From the gdax-java (as it was named prior to "coinbase pro") library the generate signature method is:

 String prehash = timestamp + method.toUpperCase() + requestPath + body; byte[] secretDecoded = Base64.getDecoder().decode(secretKey); keyspec = new SecretKeySpec(secretDecoded, "HmacSHA256"); sha256 = (Mac) GdaxConstants.SHARED_MAC.clone(); sha256.init(keyspec); return Base64.getEncoder().encodeToString(sha256.doFinal(prehash.getBytes())); 

At least on initial inspection the code you're using specifies using SHA512 rather than HmacSHA256, so I'd suspect that to be a probabale cause.

There is also more help with NodeJS in the right hand column here for generating the signatures.

3

Had the same issue here. For me the answer was to use luxon DateTime instead of the native js Date functions as shown in the coinbase docs.

Here is the typescript that works for me. You can use the results of this function to populate your request headers.

import crypto from 'crypto'; import { DateTime } from 'luxon'; export const auth = ( method: 'GET' | 'POST', path: string, body?: Record<string, unknown> ) => { const timestamp = DateTime.utc().toMillis() / 1000; let message = timestamp + method + path; if (body) { message += JSON.stringify(body); } const secret = Buffer.from('YOUR_SECRET','base64'); const hmac = crypto.createHmac('sha256', secret); return { 'CB-ACCESS-KEY': 'YOUR_KEY', 'CB-ACCESS-PASSPHRASE': 'YOUR_PASSPHRASE', 'CB-ACCESS-SIGN': hmac.update(message).digest('base64'), 'CB-ACCESS-TIMESTAMP': timestamp.toString() }; }; 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like