Tim
Tim

Reputation: 123

Coinbase Pro authentication: No valid signature

I’m attempting to authenticate to Coinbase Pro from a Google Script. I’ve managed to do this already in Postman using CryptoJS, but I’m running into issues generating the CB-ACCESS-SIGN signature header. I’ve set up a test using a test key and secret string to figure out the differences between CryptoJS.HmacSHA256 and Utilities.computeHmacSha256Signature, the implementation Google offers, and noticed a difference in parameters: CryptoJS.HmacSHA256 expects a secret as WordArray while Utilities.computeHmacSha256Signature expects a secret as string.

In Postman I'm doing the following to get the wordarray of my apiSecret to pass to CryptoJS.HmacSHA256:

var hash = CryptoJS.enc.Base64.parse(pm.variables.get('apiSecret'));

In my Google script I'm doing the sam

var hash = Utilities.base64Decode(apiSecretB64)

I've tried debugging this with the same secret and message, but I'm getting different results.

My implementation in Postman:

function computeSignature(request) {
    const data      = request.data;
    const method    = request.method.toUpperCase();
    const path      = getPath(request.url);
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    const apiSecret = CryptoJS.enc.Base64.parse(pm.variables.get('apiSecret'));
    const hash      = CryptoJS.HmacSHA256(message, apiSecret);

    const hashInBase64 = CryptoJS.enc.Base64.stringify(hash);

    return hashInBase64;
}

And my implementation in Google Script:

function computeSignature(request, path, timestamp) {
    const data      = request.data;
    const method    = request.method;
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    var apiSecret = Utilities.base64Decode(apiSecretB64);

    var hash = Utilities.computeHmacSha256Signature(message, apiSecret);
    hash = Utilities.base64Encode(hash);

    return hash;
}

Does anyone know why I'm getting different results?

Upvotes: 1

Views: 328

Answers (1)

Tim
Tim

Reputation: 123

I've managed to solve the issue by converting the message from string to a byte array:

function computeSignature(request, path, timestamp) {
    const data      = request.data;
    const method    = request.method;
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    var apiSecretByteArr = Utilities.base64Decode(apiSecretB64);
    var messageByteArr = Utilities.base64Decode(Utilities.base64Encode(message));

    var hash = Utilities.computeHmacSha256Signature(messageByteArr, apiSecretByteArr);

    return Utilities.base64Encode(hash);
}

There is probably a better way of doing this, but at least the correct signature is now being computed.

Upvotes: 1

Related Questions