Step 1: Steps to generate header secret and encrypted data


Generate header_secret:

{
 "client_id":"42Zuw71Ok7e2TGAgHPKttM7PFGMspJLLy3ewq15dhgjtGM9l",
 "client_secret":"MDB9krmA8OqYdgjTKflkXXU7BTNAJgVDEWBmhWjQ8YBvAPNKNPLbxnJGSKcKiEV9",
 "epoch": "1724136430"
}
Key :- (This key is unique for each client) (Will Provided by iServeU)

Sample Code:

 
val dataToEncrypt = JSONObject().apply { put(StringConstants.DEVICE_SL_NO, deviceSlNo)
put(StringConstants.USER_NAME, Constants.transactionDataModel?.loginId) }
 

 

Step 2: Get epoch using code


Convert this JSON to String then pass the string and key into encrypt method.

 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
 {
  val epochTime = Instant.now().epochSecond
 }

 

Step 3: How to call an encrypt the Header secret


Sample Code:

 
val encryptedData = generateEncryptedData(dataToEncrypt.toString().toByteArray(),
ENCRYPTION_KEY)
 

Note:

ENCRYPTION_KEY will be provided by iServeU.

Encrypt method (Kotlin):

 
private fun generateEncryptedData(dataToEncrypt : ByteArray, key: String?): String?
   {
     val AES_KEY_SIZE: Int = 256
     val AES_BLOCK_SIZE: Int = 16
     try {
         val iv = ByteArray(AES_BLOCK_SIZE)
         val random = SecureRandom()
         random.nextBytes(iv)
  val decodedKey: ByteArray = Base64.decodeBase64(key)
         val secretKeySpec = SecretKeySpec(decodedKey, "AES")
  val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
         cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, IvParameterSpec(iv))
         val paddedData: ByteArray = pkcs7Padding(dataToEncrypt, AES_BLOCK_SIZE)
         val encrypted = cipher.doFinal(paddedData)
         val result = ByteArray(iv.size + encrypted.size)
         System.arraycopy(iv, 0, result, 0, iv.size)
         System.arraycopy(encrypted, 0, result, iv.size, encrypted.size)
         return Base64.encodeBase64String(result)
  } catch (e: Exception) {
         return null
  }
}

 

 
private fun pkcs7Padding(data: ByteArray, blockSize: Int): ByteArray
  {
    val padding = blockSize - (data.size % blockSize)
    val padText = ByteArray(padding)
    Arrays.fill(padText, padding.toByte())
    val paddedData = ByteArray(data.size + padding)
    System.arraycopy(data, 0, paddedData, 0, data.size)
    System.arraycopy(padText, 0, paddedData, data.size, padding)
    return paddedData
  }

Encrypt method (JAVA):

 
// —------- Encryption Method —-----------
    public static String EncryptRequest(Object incomingJsonReq, String key) throws Exception {
        byte[] decodedKey = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            decodedKey = Base64.getDecoder().decode(key);
        } else {
            Log.e("@@", "Using device with OS < O");
            decodedKey = android.util.Base64.decode(key, android.util.Base64.NO_WRAP);
        }
        // Generate a random IV
        byte[] iv = new byte[16];
        SecureRandom random = new SecureRandom();
        random.nextBytes(iv);
        // Convert payload to byte array
        byte[] payloadBytes = incomingJsonReq.toString().getBytes();
        // Initialize AES cipher
        SecretKeySpec secretKeySpec = new SecretKeySpec(decodedKey, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
        // Encrypt the data
        byte[] encryptedBytes = cipher.doFinal(payloadBytes);
        // Combine IV and encrypted data
        byte[] result = new byte[iv.length + encryptedBytes.length];
        System.arraycopy(iv, 0, result, 0, iv.length);
        System.arraycopy(encryptedBytes, 0, result, iv.length, encryptedBytes.length);
        // Return Base64 encoded result
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            return Base64.getEncoder().encodeToString(result);
        } else {
            return android.util.Base64.encodeToString(result, android.util.Base64.NO_WRAP);
        }
    }

 

Note: 

The encrypted method will return one header_secret which will be sent in place of client id and client secret.

Note: 

In place of client_id and client_secret send headerSecrets.

 

Step 4: Data Model Base64 Encryption of Transaction data


 

 
val dataModel = DataModel(/*add all required params*/)
val gson = Gson()
val getData = gson.toJson(dataModel)
val bytes = getData.toString().toByteArray()
val responseToBase64 = String(android.util.Base64.encode(bytes, android.util.Base64.NO_WRAP))

 

Step 5: Intent Data to Send


 
val intent = Intent(this@MainDemoActivity, MatmActivity::class.java)
intent.putExtra("data", responseToBase64)
intent.putExtra("supportEncryption", true)
startActivity(intent)

 

Step 6: Callback data handle


 
override fun onMatmSDKFinish(message: String?)
 {
   val decodedData = android.util.Base64.decode(message , android.util.Base64.NO_WRAP)
   val actualData = String(encryptedData, Charsets.UTF_8)
   activityMainBinding?.callbackText?.text = "message: $decodedData"
 }