How do I set cryptoJS.sha256 output to binary in Postman pre-request script

10,039

Check out the answer in this thread. It helped me with the my problem and may be what is happening in your case also. All it is necessary is break the input of the HMAC into two parts.

Share:
10,039
Frankenmint
Author by

Frankenmint

Cause I lay it down THICK!!! Expert of nothing= Generalist of EVERYTHING!!!!!

Updated on June 04, 2022

Comments

  • Frankenmint
    Frankenmint almost 2 years

    I am trying to create an HMAC signature in Postman using a pre-request script. Without going too far into the details of implementation,

    I have confirmed that my means for generating the signature is messed up. I can see what the expected result should be with a proof of concept example but I’m missing something somewhere and cannot tell if it is in the conversion. I’ve read around from other questions on SO that binary is the default provided by cryptojs internally and that simply calling for the hash is the equivalent of asking for the digest with conversions completed for you. Here is the code I’m trying to run in postman and the working implementation code as shown in nodeJS.

    var CryptoJS = require("crypto-js");
    
    const d = new Date();
    const timestamp = d.getTime();
    const postData = {};
    postData.nonce = 100;  //timestamp * 1000; //nanosecond
    postman.setEnvironmentVariable('nonce', postData.nonce); 
    
    const secret = CryptoJS.enc.Base64.parse(pm.environment.get("apiSecret"));
    const path = pm.globals.get("balanceMethod");
    const message =  CryptoJS.SHA256( encodeURI(postData.nonce + postData)) ; // ...
    
    const hmacDigest = CryptoJS.HmacSHA512(path + message, secret);
    postman.setEnvironmentVariable('API-Signature', CryptoJS.enc.Base64.stringify(hmacDigest)); 
    console.log(CryptoJS.enc.Base64.stringify(hmacDigest));
    

    Does this apply to my situation in that I’d need to convert my sha256 message into a bytes array in order to work?

    Reference code for building implementation that does work with nodeJS:

    const getMessageSignature = (path, request, secret, nonce) => {
        const message       = qs.stringify(request);
        const secret_buffer = new Buffer(secret, 'base64');
        const hash          = new crypto.createHash('sha256');
        const hmac          = new crypto.createHmac('sha512', secret_buffer);
        const hash_digest   = hash.update(nonce + message).digest('binary');
        const hmac_digest   = hmac.update(path + hash_digest, 'binary').digest('base64');
        return hmac_digest;
    };
    

    Same reference code for building implementation in python3:

        req['nonce'] = 100 #int(1000*time.time())
        postdata = urllib.parse.urlencode(req)
    
        # Unicode-objects must be encoded before hashing
        encoded = (str(req['nonce']) + postdata).encode()
        message = urlpath.encode() + hashlib.sha256(encoded).digest()
        signature = hmac.new(base64.b64decode(self.secret),
                             message, hashlib.sha512)
        sigdigest = base64.b64encode(signature.digest())
    

    The only post data I'm sending is the Nonce at this time and I've purposely set it to 100 to be able to replicate the result to fix the generated signature. Seems close but not matching result. The python and nodeJS do match expected results and work properly.