Hello there, I spent almost a week on trying to get what I want, but to na avail, so please somebody with experience with security in BLE on ESP32(-C3) help...
So, as a part of a bigger project, I want my ESP32-C3 to run a BLE server, and a phone to connect to it.
Since my device has no UI, I need a fixed PIN.
I want no bonding, that is everytime the phone connects the device should not let it in without prior the fixed PIN authentification (does not apply to data exchange, only to connecting)
I have sketch below, and it behaves strange - if I try to connect through system settings of the phone I am asked for PIN, but applications like nRF connect and BLE scanner simply bypass the authentification.
With so many options in the BLE, I believe I am missing something, ot want to achieve something impossible, yet looking basic
Many thanks in advance, here is my sketch
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLESecurity.h>
// Custom Security Callbacks to handle passkey request, confirmation, and security request
class MySecurityCallbacks : public BLESecurityCallbacks {
public:
uint32_t onPassKeyRequest() override {
Serial.println("Passkey request, providing static passkey...");
return 123456; // Static passkey
}
void onPassKeyNotify(uint32_t pass_key) override {
Serial.print("Passkey Notify: ");
Serial.println(pass_key);
}
bool onSecurityRequest() override {
Serial.println("Security request received, proceeding with authentication...");
return true; // Allow the security request
}
bool onConfirmPIN(uint32_t pin) override {
Serial.print("PIN confirmation: ");
Serial.println(pin);
return true; // Accept the PIN
}
void onAuthenticationComplete(esp_ble_auth_cmpl_t auth_cmpl) override {
if (auth_cmpl.success) {
Serial.println("Authentication successful!");
} else {
Serial.println("Authentication failed.");
}
}
};
// BLE Server Callbacks
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
Serial.println("Device connected");
}
void onDisconnect(BLEServer* pServer) {
Serial.println("Device disconnected");
// Restart advertising
pServer->getAdvertising()->start();
}
};
void setup() {
Serial.begin(115200);
// Initialize BLE Device
BLEDevice::init("ESP32_Secure_Device");
BLEDevice::setSecurityCallbacks(new MySecurityCallbacks());
// Create BLE server and set callbacks
BLEServer* pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create BLE service and characteristic
BLEService* pService = pServer->createService(BLEUUID("12345678-1234-1234-1234-123456789abc"));
BLECharacteristic* pCharacteristic = pService->createCharacteristic(
BLEUUID("87654321-4321-4321-4321-cba987654321"),
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("Secure Data");
// Set up BLE Security
BLESecurity* pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM); // Require MITM with secure connections
pSecurity->setCapability(ESP_IO_CAP_IO); // Requires passkey or numeric comparison
pSecurity->setStaticPIN(123456); // Set static passkey
pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
// Start BLE service
pService->start();
// Start advertising
BLEAdvertising* pAdvertising = pServer->getAdvertising();
pAdvertising->start();
Serial.println("BLE server with enforced passkey authentication started...");
}
void loop() {
// Main loop logic (if any)
}