2

I have an Angular project in which I have to implement datatrans payment. But I am not able to generate sign for payment.

I am following process given on this link (enter link description here) to generate sign.

But i am not able to achive it.

I am using angular library crypto-js to generate HMAC-SHA-256 signed string.

Here is my javascript code.

const merchantId = 'xxxxxxx';
const refNo = '1234567890';
const amount = 0;
const currency = 'CHF';
const theme = 'DT2015';
const paymentmethod = 'VIS';

const stringSs = merchantId+amount+currency+refNo;

const base = 16;
// My Hmac Key
const s = 'fa3d0ea1772cf21e53158283e4f123ebf1eb1ccfb15619e2fc91ee6860a2e5e48409e902b610ce5dc6f7f77fab8affb60d69b2a7aa9acf56723d868d36ab3f32';

// Step 1: Code to generate hex to byte of hmac key
const a = s.replace(/../g, '$&_').slice (0, -1).split ('_').map ((x) => parseInt (x, base));

//  Step 3: Sign the string with HMAC-SHA-256 together with your HMAC key
const signedString = HmacSHA256(a, stringSs);

// Step 4: Translate the signature from byte to hex format
const signString = enc.Hex.stringify(signedString);

Can you help me into this to suggest what i am doing wrong or in what way it can be achieved.

3 Answers 3

11

You can do it with crypto (no need of extra libraries to install)

// Typescript
import * as crypto from 'crypto';

function signKey (clientKey: string, msg: string) {
    const key = new Buffer(clientKey, 'hex');
    return crypto.createHmac('sha256', key).update(msg).digest('hex');
}
// Javascript
const crypto = require('crypto')

function signKey (clientKey, msg) {
    const key = new Buffer(clientKey, 'hex');
    return crypto.createHmac('sha256', key).update(msg).digest('hex');
}
signKey(s, stringSs)
Sign up to request clarification or add additional context in comments.

Comments

2

To answer the question for crypto-js (see https://github.com/brix/crypto-js) as requested, the following will do the trick:

// Javascript; example from datatrans documentation using a random key
stringSs ='3000017692850CHF91827364';
key='1ca12d7c0629194a9f9d0dbbc957709dd3aed385925b077e726813f0b452de6a38256abd1116138d21754cfb33964b6b1aaa375b74d3580fcda916898f553c92';
expectedSign='d7dee9ae1e542bc02bcb063a3dd3673871b2e43ccb4c230f26e8b85d14e25901';

signedString = CryptoJS.HmacSHA256(stringSs, CryptoJS.enc.Hex.parse(key));
resultSign = CryptoJS.enc.Hex.stringify(signedString);

// now resultSign == expectedSign is true :-)

Ninja Turtles approach was almost correct except of step 1, hex to byte. Use a builtin function of Crypto-JS instead and everything works as expected.

Comments

1

Modern browsers have crypto built in, no npm modules required,

Here's a rough TypeScript implementation, borrowing heavily from https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest (I expect this could be improved):

async function signString(s: string): Promise<string> {
  const msgUint8 = new TextEncoder().encode(s)
  const buf = await crypto.subtle.digest('SHA-256', msgUint8)
  const hashArray = Array.from(new Uint8Array(buf))
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''))
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.