Encryption Library

🛡️ HesabeCrypt Implementation

This section provides the complete HesabeCrypt implementation in multiple programming languages, featuring industry-standard AES-256-CBC encryption for secure data transmission.

Important Note

The encryption and decryption code snippets are provided in PHP, JavaScript for better integration options

🔒 Encryption Methods

<?php

namespace App\Libraries;

class HesabeCrypt {
    // AES Encryption Method Starts
    public static function encrypt($str, $key, $ivKey)
    {
        $str = self::pkcs5_pad($str);
        $encrypted = openssl_encrypt($str, 'AES-256-CBC', $key, OPENSSL_ZERO_PADDING, $ivKey);
        $encrypted = base64_decode($encrypted);
        $encrypted = unpack('C*', ($encrypted));
        $encrypted = self::byteArray2Hex($encrypted);
        $encrypted = urlencode($encrypted);
        return $encrypted;
    }

    private static function pkcs5_pad($text)
    {
        $blocksize = 32;
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text.str_repeat(chr($pad), $pad);
    }

    private static function byteArray2Hex($byteArray)
    {
        $chars = array_map("chr", $byteArray);
        $bin = join($chars);
        return bin2hex($bin);
    }

    // Decrypt method
    public static function decrypt($encryptedData, $key, $ivKey)
    {
        $encryptedData = urldecode($encryptedData);
        $encryptedData = self::hex2ByteArray($encryptedData);
        $encryptedData = base64_encode(pack('C*', ...$encryptedData));
        $decrypted = openssl_decrypt($encryptedData, 'AES-256-CBC', $key, OPENSSL_ZERO_PADDING, $ivKey);
        return self::pkcs5_unpad($decrypted);
    }

    private static function hex2ByteArray($hex)
    {
        return array_map('hexdec', str_split($hex, 2));
    }

    private static function pkcs5_unpad($text)
    {
        $pad = ord($text[strlen($text) - 1]);
        return substr($text, 0, -$pad);
    }
}

Create HesabeCrypt.js file

"use strict";

const aesjs = require("aes-js");

class HesabeCrypt {
  constructor(secret, iv) {
    this.key = secret;
    this.iv = iv;
  }

  encryptAes(txt) {

        var txtBytes = aesjs.padding.pkcs7.pad(aesjs.utils.utf8.toBytes(txt));
        var aesCbc = new aesjs.ModeOfOperation.cbc(this.key, this.iv);
        var encBytes = aesCbc.encrypt(txtBytes);
        var encHex = aesjs.utils.hex.fromBytes(encBytes);
        return encHex;
    }

    decryptAes(encHex) {
        var encBytes = aesjs.utils.hex.toBytes(encHex);
        var aesCbc = new aesjs.ModeOfOperation.cbc(this.key, this.iv);
        var decBytes = aesCbc.decrypt(encBytes);
        var decTxt = aesjs.utils.utf8.fromBytes(decBytes);
        var strippedTxt = this.pkcs5Strip(decTxt);
        return strippedTxt;
    }

    pkcs5Pad(data) {
        var blockSize = 32;
        var padLen = blockSize - (data.length % blockSize);
        var paddedTxt = (data + this.strRepeat(String.fromCharCode(padLen), padLen));
        return paddedTxt;
    }

    pkcs5Strip(data) {
        var dataLen = data.length;
        if (dataLen < 32) {
            throw new Error('Invalid data length. Block size must be 32 bytes');
        }
        var padderCodeInt = parseInt(data.charCodeAt(dataLen - 1));
        if (padderCodeInt > 32) {
            throw new Error('PKCS#5 padding byte out of range');
        }
        var len = dataLen - padderCodeInt;
        var strippedTxt = data.substr(0, len);
        return strippedTxt;
    }

    strRepeat(input, multiplier) {
        var y = '';
        while (true) {
            if (multiplier & 1) {
                y += input;
            }
            multiplier >>= 1;
            if (multiplier) {
                input += input
            } else {
                break;
            }
        }
        return y;
    }

}

export default HesabeCrypt;

Import HesabeCrypt.js file


import aesjs from "aes-js";
import hesabeCrypt from "../HesabeCrypt.js";  

export const getEncryptedData = value => {
  let secret_key = 'XXXXX' // Secret key provided by Hesabe
  let iv_key = 'XXXXX'     // IV key provided by Hesabe

  if(value) {
      let secret = secret_key  // merchant secret key
      let ivCode = iv_key      // merchant iv code
  
      let key = aesjs.utils.utf8.toBytes(secret);
      let iv = aesjs.utils.utf8.toBytes(ivCode);
  
      let instance = new hesabeCrypt(key, iv);
  
      let text = value;
      let encrypted = instance.encryptAes(JSON.stringify(text));
      let encrypted_data = encrypted;
  
      return encrypted_data;
  }
};

🔓 Decryption Methods

<?php
// Decryption Method for AES Algorithm Starts

public static function decrypt($code, $key, $ivKey)
{
    if (!(ctype_xdigit($code) && strlen($code) % 2 == 0)) {
        return false;
    }
    $code = self::hex2ByteArray(trim($code));
    $code = self::byteArray2String($code);
    $iv = $key;
    $code = base64_encode($code);
    $decrypted = openssl_decrypt($code, 'AES-256-CBC', $key, OPENSSL_ZERO_PADDING, $ivKey);
    return self::pkcs5_unpad($decrypted);
}

private static function hex2ByteArray($hexString)
{
    $string = hex2bin($hexString);
    return unpack('C*', $string);
}

private static function byteArray2String($byteArray)
{
    $chars = array_map("chr", $byteArray);
    return join($chars);
}

private static function pkcs5_unpad($text)
{
    $pad = ord($text{strlen($text) - 1});
    if ($pad > strlen($text)) {
        return false;
    }
    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
        return false;
    }
    return substr($text, 0, -1 * $pad);
}

import aesjs from "aes-js";
import hesabeCrypt from "../HesabeCrypt.js";  

export const getDecryptedData = value => {
  let secret_key = 'XXXXX' // Secret key provided by Hesabe
  let iv_key = 'XXXXX'     // IV key provided by Hesabe

  if(value) {
      let secret = secret_key  // merchant secret key
      let ivCode = iv_key      // merchant iv code
  
      let key = aesjs.utils.utf8.toBytes(secret);
      let iv = aesjs.utils.utf8.toBytes(ivCode);
  
      let instance = new hesabeCrypt(key, iv);
  
      let text = value;
      let decrypted = instance.decryptAes(text);
      let decrypted_data = JSON.parse(decrypted);
      
      return decrypted_data;
  }
};

🔧 Security Features

Security Features

🔐
AES-256-CBC
Industry standard encryption
🛡️
PKCS5 Padding
Secure data padding
🔑
IV Key Support
Enhanced security vector
🌐
Secure data
Secure data transmission