# Secret Key Based

A few of the Rest APIs require an encrypted request payload. The merchant application must encrypt payload with shared secret key in order to call Rocketfuel REST API's.

{% tabs %}
{% tab title="Node.Js" %}

```typescript
const CryptoJS = require("crypto-js");

//Enryption
const stringifyData = JSON.stringify(payload)
const encrypted = CryptoJS.AES.encrypt(stringifyData, key).toString();
 
//Decryption
const bytes = CryptoJS.AES.decrypt(value, key);
const data = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));  
```

{% endtab %}

{% tab title="Python" %}

```python
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)
```

{% endtab %}

{% tab title="PHP" %}

```php
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));
}
```

{% endtab %}

{% tab title="C#" %}

```csharp
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);
```

{% endtab %}

{% tab title="Java" %}

```java
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;

public class EncryptionAES {
    public static byte[] evpKDF(String key, byte[] salt, int keySize) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] keyBytes = new byte[keySize];
        byte[] previous = new byte[0];
        int generated = 0;

        while (generated < keySize) {
            md.update(previous);
            md.update(key.getBytes(StandardCharsets.UTF_8));
            md.update(salt);
            previous = md.digest();

            int bytesToCopy = Math.min(previous.length, keySize - generated);
            System.arraycopy(previous, 0, keyBytes, generated, bytesToCopy);
            generated += bytesToCopy;
        }
        return keyBytes;
    }

    public static String encryptAES(String data, String secret) throws Exception {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[8];
        random.nextBytes(salt);

        byte[] keyIv = evpKDF(secret, salt, 48);
        byte[] key = Arrays.copyOfRange(keyIv, 0, 32);
        byte[] iv = Arrays.copyOfRange(keyIv, 32, 48);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));

        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));

        byte[] saltedData = new byte[8 + salt.length + encryptedData.length];
        System.arraycopy("Salted__".getBytes(StandardCharsets.US_ASCII), 0, saltedData, 0, 8);
        System.arraycopy(salt, 0, saltedData, 8, salt.length);
        System.arraycopy(encryptedData, 0, saltedData, 16, encryptedData.length);

        return Base64.getEncoder().encodeToString(saltedData);
    }

    public static void main(String[] args) throws Exception {
        String json = "{\"merchantId\":\"MERCHANT_ID\",\"totop\":\"\"}";
        String secret = "SECRET";

        String encrypted = encryptAES(json, secret);
        System.out.println("Encrypted: " + encrypted);
    }
}
```

{% endtab %}
{% endtabs %}
