Generating Signature

This code can be used in scenarios where secure API communication is necessary, such as in financial applications where the authenticity of transactions must be verified. By generating a hash of the request data, the program ensures that any tampering with the request payload would result in a different hash, thus providing a way to detect unauthorized changes.

Message

Generate signature

FieldTypeDescription
Secret KeystringThis when you create client from FinanOne
MethodstringGET/PUT/POST/DELETE
Relative Pathstring/api/v1/transfer/verify-otp (this is example after base HOST)
TimestampunixTIme.now().Unix() -> Must not > current 30s
Encoded Payloadstring{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}
This body do not spacing or anything else

Secret Key

Please contact the support team to get secret_key (Who owner account in FinanOne that can create your client)

Hash logical

secretkey_method_relativepath_encodedpayload_timestamp (hash256)

Hash Function

A cryptographic hash function employed by HMAC for generating the signature.

package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
)

func main() {
	secretKey := "s3r3c_k3y"
	method := "POST"
	url := "/api/v1/transfer/verify-otp"
	body := `{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}`
	timeStamp := "1724986946"
	
	// Compact JSON to remove unnecessary spaces
	jsonCompat, _ := CompactJSON([]byte(body))
	
	// Create a hash using the compacted JSON and other data
	hashData := HashSHA256(fmt.Sprintf("%s_%s_%s_%s_%s", secretKey, method, url, jsonCompat, timeStamp))
	fmt.Println(hashData)
}

func HashSHA256(hashData string) string {
	hash := sha256.New()
	hash.Write([]byte(hashData))
	hashedBytes := hash.Sum(nil)
	return hex.EncodeToString(hashedBytes)
}

func CompactJSON(input []byte) (string, error) {
	var compactedBuffer bytes.Buffer
	err := json.Compact(&compactedBuffer, input)
	if err != nil {
		return "", err
	}

	return compactedBuffer.String(), nil
}

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.io.JsonStringEncoder;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) {
        String secretKey = "s3r3c_k3y";
        String method = "POST";
        String url = "/api/v1/transfer/verify-otp";
        String body = "{\"id\":\"7fc5e181-aae3-4021-8ce0-6a53aa71990d\",\"pass_code\":\"1828288371923881984\"}";
        String timeStamp = "1724986946";
        
        // Compact JSON to remove unnecessary spaces
        String jsonCompat = compactJSON(body);
        
        // Create a hash using the compacted JSON and other data
        String hashData = hashSHA256(String.format("%s_%s_%s_%s_%s", secretKey, method, url, jsonCompat, timeStamp));
        System.out.println(hashData);
    }

    public static String hashSHA256(String hashData) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(hashData.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder(2 * bytes.length);
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }

    public static String compactJSON(String input) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Object json = objectMapper.readValue(input, Object.class);
            return objectMapper.writeValueAsString(json);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Failed to compact JSON", e);
        }
    }
}

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

const crypto = require('crypto');

const secretKey = "s3r3c_k3y";
const method = "POST";
const url = "/api/v1/transfer/verify-otp";
const body = '{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}';
const timeStamp = "1724986946";

// Compact JSON to remove unnecessary spaces
const jsonCompat = JSON.stringify(JSON.parse(body));

// Create a hash using the compacted JSON and other data
const hashData = hashSHA256(`${secretKey}_${method}_${url}_${jsonCompat}_${timeStamp}`);
console.log(hashData);

function hashSHA256(data) {
  return crypto.createHash('sha256').update(data).digest('hex');
}

import hashlib
import json

secret_key = "s3r3c_k3y"
method = "POST"
url = "/api/v1/transfer/verify-otp"
body = '{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}'
timestamp = "1724986946"

# Compact JSON to remove unnecessary spaces
json_compat = json.dumps(json.loads(body), separators=(',', ':'))

# Create a hash using the compacted JSON and other data
hash_data = hashlib.sha256(f"{secret_key}_{method}_{url}_{json_compat}_{timestamp}".encode()).hexdigest()
print(hash_data)

<?php

$secretKey = "s3r3c_k3y";
$method = "POST";
$url = "/api/v1/transfer/verify-otp";
$body = '{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}';
$timeStamp = "1724986946";

// Compact JSON to remove unnecessary spaces
$jsonCompat = json_encode(json_decode($body));

// Create a hash using the compacted JSON and other data
$hashData = hash('sha256', "$secretKey_$method_$url_$jsonCompat_$timeStamp");
echo $hashData;
?>

using System;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

class Program
{
    static void Main()
    {
        string secretKey = "s3r3c_k3y";
        string method = "POST";
        string url = "/api/v1/transfer/verify-otp";
        string body = "{\"id\":\"7fc5e181-aae3-4021-8ce0-6a53aa71990d\",\"pass_code\":\"1828288371923881984\"}";
        string timeStamp = "1724986946";

        // Compact JSON to remove unnecessary spaces
        string jsonCompat = CompactJSON(body);

        // Create a hash using the compacted JSON and other data
        string hashData = HashSHA256($"{secretKey}_{method}_{url}_{jsonCompat}_{timeStamp}");
        Console.WriteLine(hashData);
    }

    static string HashSHA256(string data)
    {
        using (SHA256 sha256 = SHA256.Create())
        {
            byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(data));
            return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
        }
    }

    static string CompactJSON(string json)
    {
        JObject parsed = JObject.Parse(json);
        return parsed.ToString(Formatting.None);
    }
}

Generated signature in client will be attached in request header by key x-finan-signature along with client_id by key x-finan-key

📘

Obtain client Id

Please contact the support team to get client_id

Example

Content-Type: application/json
x-client-id: <client_id>
x-signature: <signature>
x-timestamp: <timestamp>