Building a Secure Heart Rate Monitoring Framework for Implantable Medical Devices Using ESP32 and MAX30102

Deva HarshaDeva Harsha
5 min read

Hey everyone! I'm excited to share my latest project: a security-focused framework for implantable medical devices (IMDs). As a tech enthusiast diving into IoT and biomedical engineering, I wanted to tackle the growing concerns around IMD security. Think pacemakers, insulin pumps, or even neural implants—these devices save lives but are vulnerable to hacks that could alter data or drain batteries. My prototype simulates secure data transmission from a heart rate sensor, using an ESP32 microcontroller and MAX30102 pulse oximeter. It's not truly implantable (ESP32 is too bulky for that), but it's a proof-of-concept that demonstrates encryption, authentication, and reliable monitoring.

This project was inspired by real-world vulnerabilities, like those exposed in pacemakers where attackers could remotely reprogram devices. I built this in a few weeks, and today I'll walk you through the setup, code, security features, challenges, and what I learned. Let's dive in!

Project Overview

The core idea is to create a system that:

  • Measures heart rate using a non-invasive sensor.

  • Encrypts and authenticates the data before sending it over WiFi to a server via MQTT.

  • Ensures reliability with features like finger detection to avoid false readings.

In a real IMD scenario, this could represent telemetry from an implanted sensor sending vital signs to a doctor's dashboard. The ESP32 handles processing and networking, while the MAX30102 detects pulse via IR light. Data is sampled at 50 Hz, averaged for accuracy, and published securely.

Why security? IMDs operate on low power and can't afford heavy crypto, but breaches could be fatal—imagine falsified heart rates triggering unnecessary shocks in a defibrillator. My framework uses AES-256 encryption and HMAC-SHA256 to protect against eavesdropping and tampering.

Hardware Components

Here's what I used:

  • ESP32 Development Board: The brain of the operation. It's cheap, powerful, and has built-in WiFi/BLE. I chose it for its GPIO pins to interface with the sensor.

  • MAX30102 Pulse Oximeter Sensor: This little module uses red and IR LEDs to measure blood flow changes, calculating beats per minute (BPM). It's similar to what's in fitness trackers but adaptable for medical prototypes.

  • Jumper Wires and Breadboard: For quick prototyping.

  • Power Supply: USB for development, but in a real implant, it'd be battery-optimized.

Total cost? Under 2000rs. I connected the MAX30102 to the ESP32 via I2C (SDA on pin 21, SCL on pin 23).

Software Setup and Implementation

I wrote the code in Arduino IDE for ESP32. Key libraries:

  • Wire.h for I2C.

  • MAX30105.h and heartRate.h (note: MAX30105 is compatible with MAX30102; it's a library tweak).

  • WiFi.h and PubSubClient.h for networking.

  • AESLib.h, SHA256.h, and base64.h for security.

Key Code Sections

  1. Setup:

    • Connect to WiFi (SSID and password hardcoded—change for your network!).

    • Initialize MQTT client to a local broker (IP: 192.168.1.2, port 1884).

    • Configure the sensor: LED brightness at 50 (to avoid saturation), sample rate 400 Hz, etc.

    • Print settings to serial for debugging.

  2. Loop:

    • Sample IR values every 20ms.

    • Detect finger presence (IR threshold: 20,000 to reduce false positives).

    • Use checkForBeat() to find pulses, calculate BPM, and average over 4 readings.

    • If valid BPM (40-180 range), encrypt and publish.

  3. Security Pipeline (in publishHeartRate):

    • Convert BPM to string.

    • Pad to AES block size (PKCS#7).

    • Encrypt with AES-256-CBC (key: 32-byte string).

    • Base64 encode ciphertext.

    • Compute HMAC-SHA256 on the encoded data.

    • Build JSON: {"data": "encrypted_base64", "hmac": "hmac_hex"}.

    • Publish to secure/heartRate; also send unencrypted debug to heartRate/debug.

Here's a snippet of the encryption part for clarity:

cpp

// Padding and Encryption

int padded_size = plain_text.length();

if (padded_size % 16 != 0) {

padded_size = (padded_size / 16 + 1) * 16;

}

byte plain_bytes[padded_size];

memset(plain_bytes, 0, padded_size);

memcpy(plain_bytes, plain_text.c_str(), plain_text.length());

byte pad_value = padded_size - plain_text.length();

for (int i = plain_text.length(); i < padded_size; i++) {

plain_bytes[i] = pad_value;

}

byte encrypted[padded_size];

aesLib.encrypt(plain_bytes, padded_size, encrypted, aes_key, 256, aes_iv);

// Base64

char base64_output[base64_enc_len(padded_size) + 1];

base64_encode(base64_output, (char*)encrypted, padded_size);

The HMAC is calculated manually using SHA256 inner/outer keys—solid but could be optimized.

Security Features in Depth

This is the heart (pun intended) of the project:

  • Confidentiality: AES-256-CBC ensures data privacy. Even if intercepted, BPM is unreadable without the key.

  • Integrity & Authentication: HMAC-SHA256 verifies no tampering and authenticates the sender.

  • Defenses Against Common Attacks:

    • Replay: Timestamps could be added (future improvement).

    • DoS: Limited reconnection attempts.

    • Side-Channels: Not addressed here, but real IMDs need hardware protections.

In tests, I simulated a receiver (Mosquitto broker) that decrypts and checks HMAC—worked flawlessly. For IMDs, this aligns with FDA guidelines on cybersecurity.

Challenges and Lessons Learned

  • Sensor Accuracy: Initial readings were noisy; tweaking LED brightness and thresholds helped. Real implants need biomedical-grade sensors.

  • Power Consumption: ESP32 guzzles power for WiFi—fine for prototypes, but IMDs demand ultra-low-power chips like those from Texas Instruments.

  • Key Management: Hardcoded keys are a no-go for production; I plan to add dynamic key exchange.

  • Scalability: MQTT is great for IoT, but for implants, BLE or proprietary protocols might be better to minimize range/exposure.

  • Testing: I used serial monitors and Wireshark to sniff packets—confirmed encryption holds up.

One big takeaway: Balancing security with usability is tough. Over-encrypting could delay emergency access, so designs need "break-glass" modes.

Results and Demo

In action, it detects finger placement, reads BPM (e.g., 75-85 at rest), and publishes securely every few seconds. Average latency: <1s. No false positives after threshold tweaks.

If I demo this , you'll see serial output like:

IR Value: 25000, Threshold: 20000

Finger detected! Reading pulse...

Current BPM: 78.0, Avg BPM: 77

Publishing Heart Rate: 77 BPM

Secure message published successfully!

Conclusion and Future Work

This project proves that affordable hardware can prototype secure IMD frameworks, highlighting the need for crypto in medical IoT. It's open-source—feel free to fork my code on GitHub (link in bio). Next, I'll integrate BLE, add anomaly detection (e.g., flag weird BPM patterns as attacks), and maybe use ML for better beat detection.

What do you think? Have IMD security ideas? Drop a comment! Thanks for reading—stay secure out there.

0
Subscribe to my newsletter

Read articles from Deva Harsha directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Deva Harsha
Deva Harsha