Rocketfuel Blockchain
  • Welcome to Rocketfuel
  • Core Concepts
    • Overview
    • Partners
    • Merchants
    • Shoppers
    • Exchanges
    • QR Payments
    • Bank Payments
    • Invoices
    • Settlements
  • Plug-ins and SDKs
    • Bigcommerce
    • Magento
    • PrestaShop
    • WooCommerce
    • Webflow
    • Web SDK
  • Developer Guides
    • Overview
    • Quick Start
    • API Reference
      • PayIns
        • Overview
        • Encryption Algorithm
          • Public Key Based
          • Secret Key Based
        • Authentication
          • Authenticate a merchant
          • Authentication Without Email / Password
        • RocketFuel UI Integration
          • Generate Invoice Link
          • Payment Processing
            • RKFL Payment Page
            • RKFL Payment Widget
          • Transaction Lookup
            • Lookup using Auth
            • Lookup using Public Key
          • Webhooks
          • Handling Partial Payments
        • Custom UI Integration
          • Cryptocurrencies listing
          • Generate QR Code
          • QR Payment Status
          • Transactions Lookup
          • Webhooks
          • Handle Partial Payment
        • Utility APIs
          • Subscriptions/Recurring Payments
          • Store info
          • Shopper
            • Shopper manual signup
            • Verify shopper's email id
            • Shopper manual login
            • Shopper info
            • Shopper wallet balance
          • Exchange Payment
            • Exchanges listing
            • Pre-payment validation check
            • Payable amount
            • Trigger Exchange payment
          • Transaction listing
          • Order info
      • Payout
        • Overview
        • Add Payee
        • API Guide
        • Webhooks
    • Swagger API
  • Integrations
    • RocketFuel Integration
      • Objective
      • Target Audience
      • Product Feature overview
      • "How To" Guide
        • Sign up as a Merchant
        • KYC Verification
        • Using the RocketFuel API for Custom Integration
        • Using the RocketFuel Pre-built Solutions for Custom Integration
        • How to Use Testnet for Transactions
      • FAQ and Tips
  • Web UI
  • User Guide and Help Videos
    • White Label Requirements
    • ACI Merchant Onboarding Document (Certification)
    • Merchant User Guide
      • Sign-up Process
      • Sign-in Process
      • Merchant Dashboard
      • Transactions
      • Shoppers
      • Reports
      • Invoices
      • Users
      • Funds
      • Bank/ACH Payments
      • Instore
      • Settlements
      • Subscriptions
      • Release Notes
      • Verification
      • Help/FAQ
      • Plugins
        • How to Setup RocketFuel on Different plugins
        • How to Use Rocketfuel With Different SDKs
      • Settings
    • Shopper User Guide
      • Dashboard
      • Purchases
      • Profile
      • Exchange
      • Bank/ACH Payments
      • Help/FAQ
      • Settings
      • Subscriptions
    • Partner User Guide
      • Dashboard
        • How to Invite Merchants
        • How to Generate Auth Header for Merchants
      • Transactions
      • Refunds
      • Shoppers
      • Merchants
      • Reports
      • Subscriptions
      • Payment Settings
      • Settings
      • Release Notes
    • Super Partner Guide
      • Overview
      • How to Invite Partners
  • Release Notes
    • Change Log
Powered by GitBook
On this page
  • Obtaining Authentication Keys
  • Authentication
  • Generating access and refresh token using encrypted payload and clientId

Was this helpful?

  1. Developer Guides
  2. API Reference
  3. PayIns
  4. Authentication

Authentication Without Email / Password

PreviousAuthenticate a merchantNextRocketFuel UI Integration

Last updated 8 months ago

Was this helpful?

Obtaining Authentication Keys

Client Id and Client Secret are available over the merchant portal in the Settings menu.

Authentication

Encryption is done using AES algorithm with PKCS7 padding, CBC mode and a key size of 256. Encryption of the body payload is as follows:-

var CryptoJS = require('crypto-js');
var data = CryptoJS.AES.encrypt(JSON.stringify({
    merchantId: 'MERCHANT_ID',
    totp:''
}), 'CLIENT_SECRET').toString();

pm.variables.set("encryptedPayload", data);
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import hashlib
import base64

def generate_salt():
    return get_random_bytes(8)

def evpkdf(passphrase, salt, key_size=32, iv_size=16):
    """
    Derives a key and IV from the passphrase and salt using OpenSSL compatible method.
    """
    d = d_i = b''  # Initialize empty bytes for key and IV derivation
    while len(d) < key_size + iv_size:
        d_i = hashlib.md5(d_i + passphrase.encode('utf-8') + salt).digest()
        d += d_i
    return d[:key_size], d[key_size:key_size + iv_size]

def pad(data):
    """Pads data to a multiple of AES block size (16 bytes)."""
    padding_len = 16 - len(data) % 16
    return data + chr(padding_len) * padding_len

def encrypt_data(data, passphrase, salt):
    key, iv = evpkdf(passphrase, salt)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted_data = cipher.encrypt(pad(data).encode())
    return encrypted_data

def create_encrypted_payload(data, passphrase):
    salt = generate_salt()
    encrypted_data = encrypt_data(data, passphrase, salt)
    encrypted_data_with_salt = b"Salted__" + salt + encrypted_data
    return base64.b64encode(encrypted_data_with_salt).decode('utf-8')

# Data to be encrypted
data = {
    'merchantId': MERCHANT_ID,
    'totp': ''
}

# Convert the data to a JSON string
data_str = json.dumps(data)

# Create the encrypted payload
encrypted_payload = create_encrypted_payload(data_str, CLIENT_SECRET)
function encrypt($toEncrypt, $secret){
    $salt = openssl_random_pseudo_bytes(8);
    $salted = $dx = '';
    while (strlen($salted) < 48) {
        $dx = md5($dx . $secret . $salt, true);
        $salted .= $dx;
    }

    $key = substr($salted, 0, 32);
    $iv = substr($salted, 32, 16);

    // encrypt with PKCS7 padding
    return base64_encode('Salted__' . $salt . openssl_encrypt($toEncrypt . '', 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv));
}
using System;
using System.Security.Cryptography;
using System.Text;
using System.Linq;

public class EncryptionAES
{
    private static readonly Random SecureRandom = new Random();

    public static byte[] EvpKDF(byte[] password, byte[] salt, int keySize = 48, string hasher = "MD5", int iterations = 1)
    {
        byte[] keyMaterial = new byte[keySize];
        int generatedBytes = 0;
        byte[] block = null;
        using (var md = MD5.Create())
        {
            while (generatedBytes < keySize)
            {
                md.Initialize();

                if (block != null)
                    md.TransformBlock(block, 0, block.Length, null, 0);

                md.TransformBlock(password, 0, password.Length, null, 0);
                md.TransformFinalBlock(salt, 0, salt.Length);
                block = md.Hash;

                for (int i = 1; i < iterations; i++)
                {
                    block = md.ComputeHash(block);
                }

                int remaining = Math.Min(block.Length, keySize - generatedBytes);
                Array.Copy(block, 0, keyMaterial, generatedBytes, remaining);
                generatedBytes += remaining;
            }
        }

        return keyMaterial;
    }

    public static string EncryptAES(string data, string key)
    {
        using (var aes = Aes.Create())
        {
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            byte[] salt = new byte[8];
            SecureRandom.NextBytes(salt);

            byte[] derivedKey = EvpKDF(Encoding.UTF8.GetBytes(key), salt);
            byte[] keyBytes = derivedKey.Take(32).ToArray();
            byte[] ivBytes = derivedKey.Skip(32).Take(16).ToArray();

            aes.Key = keyBytes;
            aes.IV = ivBytes;

            using (var encryptor = aes.CreateEncryptor())
            using (var ms = new System.IO.MemoryStream())
            {
                ms.Write(Encoding.ASCII.GetBytes("Salted__"), 0, 8);
                ms.Write(salt, 0, salt.Length);

                using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                using (var sw = new System.IO.StreamWriter(cs))
                {
                    sw.Write(data);
                }

                return Convert.ToBase64String(ms.ToArray());
            }
        }
    }
}


//how to use
    var data = new { merchantId = "861331d4-aa85-42c2-8a4f-a8e78043809a",totp=""};
    string toEncrypt = JsonSerializer.Serialize(data);
    string secret = "SECRET";
    string encrypted = EncryptionAES.EncryptAES(toEncrypt, secret);
    Console.WriteLine("Encrypted: " + encrypted);
/**
* based on: www.openssl.org/docs/crypto/EVP_BytesToKey.html
*/
fun evpKDF(password: ByteArray, salt: ByteArray, keySize: Int = 48, hasher: String = "MD5", iterations: Int = 1): ByteArray {
val keyMaterial = ByteArray(keySize)
var generatedBytes = 0
var block: ByteArray? = null
val md = MessageDigest.getInstance(hasher)

while (generatedBytes < keySize) {
        md.reset()

if (block != null)
            md.update(block)

        md.update(password)
        block = md.digest(salt)

for (i in 1 until iterations)
            block = md.digest(block)

val remaining = block!!.size.coerceAtMost(keySize - generatedBytes)
System.arraycopy(block, 0, keyMaterial, generatedBytes, remaining)
        generatedBytes += remaining
    }

return keyMaterial
}

fun encryptAES(data: String, key: String): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val salt = ByteArray(8)
secureRandom.nextBytes(salt)

val derivedKey = evpKDF(key.toByteArray(), salt)
val secretKey = SecretKeySpec(derivedKey.sliceArray(0..31), "AES")
val iv = IvParameterSpec(derivedKey.sliceArray(32..47))

    cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv)

val encrypted = cipher.doFinal(data.toByteArray())
val encryptedWithIv = "Salted__".toByteArray() + salt + encrypted

return Base64.getEncoder().encodeToString(encryptedWithIv)
}

Generating access and refresh token using encrypted payload and clientId

POST api/auth/generate-auth-token

This endpoint is used for generating access and refresh tokens without using merchant email and password. It requires clientId and encrypted string generated from the encryption logic discussed above.

Request Body

Name
Type
Description

clientId*

String

Client Id can be accessed in Settings menu

encryptedPayload*

String

AES encrypted (using client secret) payload containing merchant Id and totp

{
    "ok": true,
    "result": {
        "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImM1MzlkZWVjLTYwNDktNDZlMC1hZTJjLTUwZTJhNjQ2ZmMzMSIsImlhdCI6MTY2MjczOTczOSwiZXhwIjoxNjYyODI2MTM5fQ.AkvmP2oTAfj91w5w9arOAsiAAnfg1o-Ia-3b3PkZSaw",
        "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImM1MzlkZWVjLTYwNDktNDZlMC1hZTJjLTUwZTJhNjQ2ZmMzMSIsImlhdCI6MTY2MjczOTczOSwiZXhwIjoxNjY1MzMxNzM5fQ.CFjoO4XwZpuQNBpkVoQtpUbu1_yYVIFoMO5MqDWYGeg",
        "status": 2
    }
}

If we provide the clientSecret as string it will not use it as a key but a passphrase to derive the key value using a KDF. The default KDF for this library is similar to the open SSL EVP function. (for reference: ) This function generates the actual AES keys using MD5 hashing and uses 1 iteration.

https://www.openssl.org/docs/manmaster/man3/EVP_BytesToKey.html