How do we create Signature in header using Client Public Key and Private Key

How to create signature using client public and private key with the payload for POST request.

Hi @grarkeri , welcome to the community!

We might need a little more context for your question, but I will assume that you’re trying to set a custom header based on your keys.

If your keys are in an environment variable, you can take a look at the CryptoJS library, which we make available, and do that work within a Pre-request script.

For example, if you wanted to generate a hash using SHA256, you could do something like this:

let message = "hello world"
let publicKey = pm.environment.get("publicKey")
let privateKey = pm.environment.get("privateKey")
const nonce = "" // set this to whatever you need it to be
const hashDigest = CryptoJS.SHA256(nonce + message)
console.log("hashdigest", hashDigest)
let hmacsha512 = CryptoJS.HmacSHA512(hashDigest, privateKey)
console.log("hmacsha512", hmacsha512)
const hmacDigest = btoa(hmacsha512);
console.log("hmacDigest", hmacDigest)

then you can add a header whose value is set to {{hmacDigest}} .

This presumes that this is the digest scheme that you need to follow, but should get you started. If you can help with more specifics, we can give you more exact advice.

Cheers,
Ian

1 Like

Hi Ian,

Thanks for your response. I was trying to write the pre script for the below python code. Could you give some guidance on how it can be written in pre script.

Generate the Signature - Written in Python code

Payload -

web_InitializeSession_payload = json.loads("{}")
web_InitializeSession_payload['AccountAddressCollectionMode'] = 'None'
web_InitializeSession_payload['ReturnURL'] = 'http://google.com'

web_InitializeSession_payload['RequestExpirationUTC'] = (datetime.datetime.utcnow() + datetime.timedelta(seconds=60)).isoformat()

print(json.dumps(web_InitializeSession_payload, indent=4))

# Sign the payload

web_InitializeSession_signature = privateKey.sign(
    json.dumps(web_InitializeSession_payload).encode('utf-8'),
    padding.PKCS1v15(),
    hashes.SHA256()
    )

print('Payload Signature: ', binascii.hexlify(web_InitializeSession_signature))
1 Like

hi @grarkeri ,

I can try, but I’m not sure what all of the elements of your code are doing.

const moment = require("moment")
let payload = {
  AccountAddressCollectionMode: null,
  ReturnURL: "http://google.com",
  RequestExpirationUTC: moment().utc()
}

You might try moment.milliseconds().utc() too for that last expiration, I’m not sure what kind of timestamp you’re looking for there.

I’m not sure what your privateKey.sign() method is doing, so I can’t comment on how to transform that into JavaScript here. (I’m guessing that you’re passing in method references to call within your code, so I guess you’d want to be looking at CryptoJS.SHA256 for the last parameter at least.)

There are paddings you can use in CryptoJS, but I don’t see one called “PKCS1v15”, so you’ll have to examine what yours is trying to do and see if CryptoJS has an equivalent.

  • crypto-js/pad-pkcs7
  • crypto-js/pad-ansix923
  • crypto-js/pad-iso10126
  • crypto-js/pad-iso97971
  • crypto-js/pad-zeropadding
  • crypto-js/pad-nopadding

Maybe @sahuvikramp can help here, he’s been working on CryptoJS recently?

For the binascii.hexify call, you should be able to use the btoa() method I listed in my previous example.

1 Like

Hi @ianthepostmanaut ,

My apologies for reviving this topic.
I would like to know if paragonie/sodium-plus is available as well.

I am a back end dev, but somehow I have to test via Postman the API (auth part as well) I am building.

Seems I need to mimic in Postman something like the code snippet bellow.

Meaning, somehow I guess I need to generate public - private key with in pre-request script tab, then create a detached signature of the message using the private key… which message actually lives in the Body tab. Then pass the signature via headers and hopefully if all is set correctly then on my backend implementation the verification of the client’s signature will be done using the public key.

Btw, does CryptoJs offer detached (from message) signature ?

Thanks in advance

const { SodiumPlus } = require('sodium-plus');
let sodium;

(async function () {
    if (!sodium) sodium = await SodiumPlus.auto();
    let aliceKeypair = await sodium.crypto_sign_keypair();
        let aliceSecret = await sodium.crypto_sign_secretkey(aliceKeypair);
        let alicePublic = await sodium.crypto_sign_publickey(aliceKeypair);
    
    let message = 'This is something I need to sign publicly.';

    // Detached mode:
    let signature = await sodium.crypto_sign_detached(message, aliceSecret);
    console.log(signature.toString('hex'));
    if (await sodium.crypto_sign_verify_detached(message, alicePublic, signature)) {
        console.log("Signature is valid.");
    } else {
        console.error("Invalid signature!");
    }

    // NaCl (crypto_sign / crypto_sign_open):
    let signed = await sodium.crypto_sign(message, aliceSecret);
    let opened = await sodium.crypto_sign_open(signed, alicePublic);
    console.log(opened.toString());
})();