Recipes

1: HMAC in NodeJS

const crypto = require('crypto')

const createSignature = (request, keyHex) => {
  const values = Object.values(request)
  const hmacData = values.sort().join('|')
  const hmacKey = Buffer.from(keyHex, 'hex')
  const hmacObj = crypto.createHmac('sha256', hmacKey)
  hmacObj.update(hmacData)
  return hmacObj.digest('hex')
}
const keyHex = 'c8a4e2cc008ae5cc32de78c498b1ac53b921360d611373900aead96c410b5de0'
const request = {
  project: 'd7d86391b36b4543bc1cf87cbd2ee6c9',
  payment_id: '38013333'
}
request.signature = createSignature(request, keyHex)
console.log(JSON.stringify(request))

2: HMAC in Python 3

import hmac

def create_signature(params, keyHex):
  params.sort()
  join_params = '|'.join(params)
  hash_params = bytearray()
  hash_params.extend(join_params.encode())
  hash_key =  bytearray.fromhex(keyHex)
  sign = hmac.new(hash_key, hash_params, 'sha256')
  return sign.hexdigest()
data = {
  'project': "d7d86391b36b4543bc1cf87cbd2ee6c9",
  'payment_id': "38013333"
}
secret = 'c8a4e2cc008ae5cc32de78c498b1ac53b921360d611373900aead96c410b5de0'
data['signature'] = create_signature(list(data.values()), secret)
print(data)
$ python hmac.py
{'project': 'd7d86391b36b4543bc1cf87cbd2ee6c9', 'payment_id': '38013333', 'signature': '2a15c222c7e4dbd23e14c915987eb34c908ab13e15d00a8e9fba82babf8bbada'}

3: HMAC in Go

package main
import (
  "crypto/hmac"
  "crypto/sha256"
  "encoding/hex"
  "encoding/json"
  "fmt"
  "strings"
  "sort"
)
func createSignature(request map[string]string, keyHex string) string {
  values := make([]string, 0, len(request))
  for _, value := range request {
    values = append(values, value)
  }
  sort.Strings(values)
  hmacKey, _ := hex.DecodeString(keyHex)
  hmacObj := hmac.New(sha256.New, []byte(hmacKey))
  hmacData := strings.Join(values, "|")
  hmacObj.Write([]byte(hmacData))
  return hex.EncodeToString(hmacObj.Sum(nil))
}
func main() {
  const keyHex = "c8a4e2cc008ae5cc32de78c498b1ac53b921360d611373900aead96c410b5de0"
  request := map[string]string{
    "project_id": "d7d86391b36b4543bc1cf87cbd2ee6c9",
    "payment_id": "38013333",
  }
  request["signature"] = createSignature(request, keyHex)
  jsonString, _ := json.Marshal(request)
  fmt.Println(string(jsonString))
}
$ go run hmac.go
{"payment_id":"38013333","project_id":"d7d86391b36b4543bc1cf87cbd2ee6c9","signature":"0a5ea9ee64d6dec3ccffd13c4e6e03892f8b3e8abac5f7b3af18f9509d77ce38"}

4: HMAC in Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class customHmac {
  private static final String HMAC_SHA256 = "HmacSHA256";
  private static String toHexString(byte[] bytes) {
    Formatter formatter = new Formatter();
    for (byte b : bytes) {
      formatter.format("x", b);
    }
    return formatter.toString();
  }
  public static byte[] hexStringToByteArray(String s) {
      int len = s.length();
      byte[] data = new byte[len / 2];
      for (int i = 0; i < len; i += 2) {
      data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
      + Character.digit(s.charAt(i + 1), 16));
    }
    return data;
  }
  public static String createSignature(Collection params, String keyHex) {
  Mac sha256Hmac;
  String result;
  String joined;
  try {
    Collections.sort(new ArrayList(params));
    joined = String.join("|", params);
    final byte[] byteKey = hexStringToByteArray(keyHex);
    sha256Hmac = Mac.getInstance(HMAC_SHA256);
    SecretKeySpec keySpec = new SecretKeySpec(byteKey, HMAC_SHA256);
    sha256Hmac.init(keySpec);
    byte[] macData = sha256Hmac.doFinal(joined.getBytes(StandardCharsets.UTF_8));
    result = toHexString(macData);
  } catch (InvalidKeyException | NoSuchAlgorithmException e) {
    e.printStackTrace();
    return null;
  }
  return result;
}

public static void main(String[] args) {
  final String keyHex = "c8a4e2cc008ae5cc32de78c498b1ac53b921360d611373900aead96c410b5de0";
  Mac sha512Hmac;
  Map request = new HashMap();
  request.put("project", "d7d86391b36b4543bc1cf87cbd2ee6c9");
  request.put("payment_id", "38013333");
  String signature = createSignature(request.values(), keyHex);
  if (signature != null) {
    request.put("signature", signature);
    System.out.println(request);
  }
  else {
    System.out.println("Failed create signature");
  }
}
}
$ javac customHmac.java
$ java customHmac
{signature=0a5ea9ee64d6dec3ccffd13c4e6e03892f8b3e8abac5f7b3af18f9509d77ce38, payment_id=38013333, project=d7d86391b36b4543bc1cf87cbd2ee6c9}

5: HMAC in PHP (7.4)

function create_signature($params, $keyHex)
{
  $values = array_values($params);
  sort($values, SORT_STRING);
  $join_params = implode("|", $values);
  $sign = hash_hmac('sha256',$join_params, hex2bin($keyHex), true);
  return bin2hex($sign);
};
$data = array(
  'project' => "d7d86391b36b4543bc1cf87cbd2ee6c9",
  'payment_id' => "38013333"
);
$secret = 'c8a4e2cc008ae5cc32de78c498b1ac53b921360d611373900aead96c410b5de0';
$data['signature'] = create_signature($data, $secret);
var_dump($data);
?>
$ php customHmac.php
array(3) {
["project"]=>
string(32) "d7d86391b36b4543bc1cf87cbd2ee6c9"
["payment_id"]=>
string(8) "38013333"
["signature"]=>
string(64) "0a5ea9ee64d6dec3ccffd13c4e6e03892f8b3e8abac5f7b3af18f9509d77ce38"
}

What's next?