Hash Message Authentication Code (HMAC) adalah sebuah kode yang digunakan untuk mengautentikasi keaslian pesan yang dikirimkan dari sebuah klien menuju server atau sebaliknya. HMAC. Pengguaan HMAC didasari dengan penggunaan Secret key yang disetujui antara klien dan server, serta payload adalah masukan yang digunakan untuk menghitung HASH hasil hmac.

Algoritma hash yang digunakan HMAC bervariasi, tetapi kebanyakan menggunakan algoritma SHA1 atau SHA256. Berikut ini adalah ilustrasi penggunaan HMAC antar klien dan server.

Contoh Implementasi HMAC di ESP32

#include "mbedtls/md.h"

#define HMAC_SECRET "123456"

void genHmac(char* signature, char* payload) {
  byte hmacResult[20];

  mbedtls_md_context_t ctx;
  mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; // Algoritma Yang dipakai SHA 1

  const size_t payloadLength = strlen(payload);
  const size_t keyLength = strlen(HMAC_SECRET);

  mbedtls_md_init(&ctx);
  mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1);
  mbedtls_md_hmac_starts(&ctx, (const unsigned char*)HMAC_SECRET, keyLength);
  mbedtls_md_hmac_update(&ctx, (const unsigned char*)payload, payloadLength);
  mbedtls_md_hmac_finish(&ctx, hmacResult);
  mbedtls_md_free(&ctx);

  char outDigest[45];
  int count = 0;

  for (int i = 0; i < sizeof(hmacResult); i++) {
    char str[3];

    sprintf(str, "%02x", (int)hmacResult[i]);

    outDigest[count] = str[0];
    count++;
    outDigest[count] = str[1];
    count++;
  }

  outDigest[count] = '\0';
  strcpy(signature, outDigest);
}

void setup(){
	char* hmacSignature[45];

	char* message = "Hello World";
	char* unixTime = "1692003946"

	char payload[128];
  snprintf(payload, 128, "%s,%s", message, unixTime);

	genHmac(&hmacSignature[0], payload);

	Serial.print("Generated HMAC :");
	Serial.println(hmacSignature);
}

Kode diatas menghasilkan kode hmac dengan menggunakan payload dan secret key yang sudah ditentukan. Antara Server dan Klien masing masing memiliki secret yang sama, secret ini di distribusikan melalui kanal yang aman atau melalui cara offline tidak menggunakan internet. Secret ini diperlukan untuk memvalidasi hasil hmac yang dikirimkan oleh klien.

Setelah klien (ESP32) melakukan kalkulasi hmac dengan payload yang digunakan yaitu (unixTime,message) maka pesan akan dikirimkan kepada server beserta signature hmac yang telah dikalkulasi. Kemudian server akan menerima pesan yang diterima beserta signature yang dikirimkan oleh klien. Kemudian server mengkalkulasi sendiri hmac dari pesan yang diterima oleh klien menggunakan secret key yang dimiliki oleh server. JIka hasil signaturenya sama maka pesan yang diterima adalah pesan yang sesuai dan original, tidak diubah ubah oleh orang lain. Karena signaturenya sama. Tetapi jika pada saat dikirimkan terjadi perbedaan pesan atau signature maka hasil perhitungan hmac di server akan berbeda sehingga mengindikasikan bahwa pesan telah dilakukan perubahan pada saat pengiriman atau disebut MITM (Man in the middle) attack.

Referensi

https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/hmac.html

https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/md_8h/