Skip to content

Encryption

BTHome supports AES-CCM encryption to protect your sensor data from eavesdropping and spoofing.

Without encryption:

  • Anyone within Bluetooth range can read your sensor data
  • Malicious actors could potentially spoof your sensors

With encryption:

  • Sensor data is encrypted with AES-128-CCM
  • Only devices with the encryption key can read the data
  • Message authentication prevents spoofing

Generate a random 16-byte (32 hex character) key:

Terminal window
# Using OpenSSL
openssl rand -hex 16
# Example output: a1b2c3d4e5f6071829304a5b6c7d8e9f

Or using Python:

Terminal window
python3 -c "import secrets; print(secrets.token_hex(16))"

Add the encryption_key to your BTHome configuration:

bthome:
encryption_key: "a1b2c3d4e5f6071829304a5b6c7d8e9f"
sensors:
- type: temperature
id: my_temperature
- type: humidity
id: my_humidity

The key must be:

  • Exactly 32 hexadecimal characters (16 bytes)
  • Lowercase or uppercase (will be normalized)
  • Can include spaces or dashes for readability (will be stripped)

Valid formats:

encryption_key: "a1b2c3d4e5f6071829304a5b6c7d8e9f"
encryption_key: "A1B2C3D4E5F6071829304A5B6C7D8E9F"
encryption_key: "a1b2c3d4-e5f60718-29304a5b-6c7d8e9f"

When adding an encrypted BTHome device in Home Assistant:

  1. Go to SettingsDevices & Services
  2. Find your BTHome device (it will show as encrypted)
  3. Click Configure
  4. Enter the same encryption key you used in ESPHome

Home Assistant BTHome encryption setup

esphome:
name: secure-sensor
friendly_name: Secure Sensor
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
external_components:
- source:
type: git
url: https://github.com/dz0ny/esphome-bthome
ref: main
components: [bthome]
i2c:
sda: GPIO21
scl: GPIO22
sensor:
- platform: bme280_i2c
temperature:
id: temp
name: "Temperature"
humidity:
id: humidity
name: "Humidity"
update_interval: 30s
bthome:
encryption_key: "a1b2c3d4e5f6071829304a5b6c7d8e9f"
min_interval: 30s
max_interval: 60s
sensors:
- type: temperature
id: temp
- type: humidity
id: humidity
esphome:
name: secure-sensor
friendly_name: Secure Sensor
nrf52:
board: xiao_ble
bootloader: adafruit
logger:
external_components:
- source:
type: git
url: https://github.com/dz0ny/esphome-bthome
ref: main
components: [bthome]
binary_sensor:
- platform: gpio
pin:
number: 3
mode: INPUT_PULLUP
id: door
name: "Door"
bthome:
encryption_key: "a1b2c3d4e5f6071829304a5b6c7d8e9f"
binary_sensors:
- type: door
id: door
advertise_immediately: true

BTHome uses AES-128-CCM encryption with:

  • Key size: 128 bits (16 bytes)
  • Nonce: MAC address + packet counter
  • MIC: 4-byte message integrity code
  • Counter: Prevents replay attacks

The encrypted packet structure:

packet-beta
  0-7: "Device Info"
  8-39: "Counter (4B)"
  40-71: "Encrypted Data"
  72-103: "MIC (4B)"
  • Verify the encryption key matches exactly
  • Check that the device is within Bluetooth range
  • Restart both the ESPHome device and Home Assistant
  • Ensure encryption_key is set in your configuration
  • Recompile and reflash the device
  • The device info byte should show encryption enabled (bit 0 set)