El aprovisionamiento seguro de dispositivos IoT es el proceso de dar a cada dispositivo una identidad única y las credenciales que necesita para llegar a tu broker MQTT, sin que esos secretos se filtren por el camino. Esta guía compara los principales modelos de aprovisionamiento, recorre un flujo de bootstrap práctico y muestra cómo se conectan los dispositivos aprovisionados a un broker de ConnectMQ con credenciales por dispositivo.
Qué debe conseguir el aprovisionamiento
Elijas el modelo que elijas, un buen proceso de aprovisionamiento ofrece cinco propiedades:
- Unicidad. Cada dispositivo recibe su propia credencial. Ningún par de dispositivos comparte un secreto.
- Confidencialidad. El secreto nunca es visible en texto claro para personas o sistemas que no lo necesitan, incluidos los logs y los artefactos de compilación.
- Trazabilidad. Puedes asociar cada credencial a un número de serie, un lote y un cliente.
- Revocabilidad. Puedes desactivar un dispositivo sin tocar los demás.
- Recuperabilidad. Puedes volver a aprovisionar un dispositivo tras una reparación o un restablecimiento de fábrica.
Una contraseña compartida compilada en el firmware incumple al menos tres de estas propiedades. Es el motivo más habitual por el que una sola unidad comprometida se convierte en un incidente que afecta a toda la flota.
Comparativa de modelos de aprovisionamiento
| Modelo | Cómo llega la credencial al dispositivo | Adecuado para | Riesgo principal |
|---|---|---|---|
| Inyección en fábrica | Una estación de programación escribe una credencial única durante la fabricación | Líneas de producción controladas | Secretos en los sistemas de fábrica |
| Claim certificate o secreto de bootstrap | El dispositivo sale con una identidad de bootstrap compartida o por lote y la canjea por una credencial única en el primer arranque | Flotas grandes, fabricación subcontratada | Abuso del secreto de bootstrap si no está limitado |
| Incorporación asistida por el usuario | Una app móvil o una página web local entrega las credenciales durante la configuración | Productos de consumo | Phishing, canal local inseguro |
| Introducción manual | El instalador escribe las credenciales en una página de configuración | Pilotos pequeños | Error humano, reutilización de credenciales |
Aprovisionamiento en fábrica
Durante la fabricación, una estación de programación genera u obtiene una credencial única y la escribe en el almacenamiento protegido del dispositivo, normalmente junto con el número de serie. En microcontroladores suele ser una partición NVS cifrada o un elemento seguro; en dispositivos Linux, un archivo cifrado o un almacén respaldado por TPM. La estación registra la correspondencia en tu sistema de inventario, nunca el secreto en texto claro.
Ventajas: los dispositivos salen de fábrica listos para conectarse. Inconvenientes: la red de la fábrica, esté en Monterrey, Bogotá o Valencia, pasa a manejar secretos, así que necesita control de acceso y su propio registro de auditoría, y tienes que confiar en el fabricante.
Claim certificates y flujos de bootstrap
Un claim certificate es una identidad limitada que comparte un lote de dispositivos. Su único permiso es llamar a un servicio de aprovisionamiento y solicitar una identidad única de larga duración. Varias plataformas IoT implementan este patrón, y puedes construir la misma idea tú mismo con cualquier broker:
- El dispositivo arranca con un secreto de bootstrap o claim certificate y su número de serie de hardware.
- Llama a tu servicio de aprovisionamiento por HTTPS, demostrando que posee el secreto de bootstrap.
- El servicio comprueba el número de serie en la lista de permitidos de fabricación y que no se haya reclamado antes.
- El servicio devuelve una credencial MQTT única para ese dispositivo y marca el número de serie como reclamado.
- El dispositivo guarda la credencial en un almacenamiento protegido y descarta el secreto de bootstrap, o lo conserva solo para un nuevo aprovisionamiento.
Como la identidad de reclamación no puede publicar ni suscribirse a nada, una copia filtrada permite a un atacante, como mucho, reclamar números de serie aún no reclamados, y la lista de permitidos junto con la reclamación única limita incluso eso.
Incorporación asistida por el usuario
Los dispositivos de consumo suelen ser aprovisionados por el propietario mediante una app que se conecta al dispositivo por BLE o a través de un punto de acceso Wi-Fi temporal. Cifra ese canal local, exige una prueba de presencia física como pulsar un botón y haz que la app obtenga la credencial del dispositivo desde tu backend en lugar de incrustar nada en la app.
Un flujo de bootstrap práctico para un broker MQTT
Si tu broker emite las credenciales por sí mismo, como suele hacer un broker MQTT gestionado, tu servicio de aprovisionamiento se convierte en el custodio que las reparte dispositivo a dispositivo. Con ConnectMQ emites las credenciales en el portal; cada conjunto incluye un nombre de usuario, una contraseña y un client ID vinculado a esas credenciales. Un diseño sencillo y robusto:
- Emite los conjuntos de credenciales en el portal antes de un lote de producción.
- Cárgalos en el almacén cifrado de tu servicio de aprovisionamiento, uno por cada número de serie previsto.
- Deja que los dispositivos los reclamen mediante el flujo de bootstrap descrito.
Un endpoint de aprovisionamiento mínimo, escrito en Python con Flask a modo de ejemplo:
# pip install flask
import hmac
import hashlib
import json
from flask import Flask, request, jsonify, abort
app = Flask(__name__)
BOOTSTRAP_KEY = b"load-from-a-secret-manager-not-source"
# serial -> {"claimed": bool, "cred": {...}} (usa una base de datos real en producción)
INVENTORY = json.load(open("batch-2026-10.json"))
def valid_proof(serial: str, nonce: str, proof: str) -> bool:
expected = hmac.new(BOOTSTRAP_KEY, f"{serial}:{nonce}".encode(),
hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, proof)
@app.post("/provision")
def provision():
body = request.get_json(force=True)
serial, nonce, proof = body.get("serial"), body.get("nonce"), body.get("proof")
if not (serial and nonce and proof) or not valid_proof(serial, nonce, proof):
abort(401)
entry = INVENTORY.get(serial)
if entry is None or entry["claimed"]:
abort(403)
entry["claimed"] = True # en producción, persiste esto antes de responder
return jsonify(entry["cred"]) # {"username": ..., "password": ..., "client_id": ...}
if __name__ == "__main__":
# Sírvelo detrás de HTTPS (proxy inverso con un certificado válido)
app.run(host="127.0.0.1", port=8080)
En producción, almacena los nonces para evitar ataques de repetición, limita la tasa de peticiones del endpoint, persiste el indicador de reclamado de forma atómica y genera alertas ante reclamaciones repetidas del mismo número de serie.
Conectar un dispositivo aprovisionado
Una vez que el dispositivo tiene su credencial, la conexión es una autenticación MQTT con usuario y contraseña normal sobre TLS. Un ejemplo para ESP32 con PubSubClient que lee la credencial desde NVS:
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Preferences.h>
extern const char ROOT_CA[]; // PEM de ISRG Root X1, compilado en el firmware
WiFiClientSecure net;
PubSubClient mqtt(net);
Preferences prefs;
String user, pass, clientId;
void setup() {
Serial.begin(115200);
prefs.begin("mqtt", true); // espacio de nombres de solo lectura
user = prefs.getString("user", "");
pass = prefs.getString("pass", "");
clientId = prefs.getString("cid", "");
prefs.end();
if (user.isEmpty()) { Serial.println("Not provisioned"); return; }
WiFi.begin("YOUR_SSID", "YOUR_WIFI_PASSWORD");
while (WiFi.status() != WL_CONNECTED) delay(500);
net.setCACert(ROOT_CA);
mqtt.setServer("YOUR_BROKER_HOST", 8883);
}
void loop() {
if (user.isEmpty()) { delay(1000); return; } // espera al aprovisionamiento
if (!mqtt.connected()) {
if (mqtt.connect(clientId.c_str(), user.c_str(), pass.c_str())) {
mqtt.publish(("devices/" + clientId + "/status").c_str(), "online", true);
} else {
Serial.printf("MQTT connect failed, state=%d\n", mqtt.state());
delay(10000); // espera, no satures el broker
}
}
mqtt.loop();
}
Activa el cifrado de flash y el cifrado de NVS para que la credencial almacenada no pueda leerse desde un volcado del chip de flash. Los detalles están en cómo proteger las credenciales MQTT en los dispositivos.
Reaprovisionamiento, reparaciones y retirada
El aprovisionamiento no es un evento único. Los dispositivos vuelven para reparaciones, los clientes los restablecen a valores de fábrica, cambian de propietario y acaban llegando al final de su vida útil. Planifica cada uno de estos caminos antes de que salga el primer lote:
- Restablecimiento de fábrica. Decide si un restablecimiento borra la credencial MQTT. Si lo hace, el dispositivo necesita una vía de regreso al flujo de bootstrap, lo que significa que tu servicio de aprovisionamiento debe permitir una nueva reclamación controlada, por ejemplo después de que un ticket de soporte marque el número de serie como restablecible.
- Reparaciones y cambios de placa. Cuando se sustituye una placa base, la credencial antigua se va con la placa antigua. Revócala, emite un conjunto nuevo y actualiza el inventario para que el número de serie apunte al nuevo client ID.
- Cambio de propietario. En dispositivos vendidos o transferidos entre clientes, emite credenciales nuevas en un broker que pertenezca al nuevo propietario en lugar de trasladar las antiguas.
- Retirada. Revoca la credencial en el portal el mismo día en que el dispositivo deja de estar en servicio y registra la fecha. Las credenciales abandonadas que siguen funcionando son una fuente habitual de conexiones inesperadas meses después.
Cada uno de estos caminos reutiliza los mismos componentes que el aprovisionamiento inicial y la rotación de credenciales: emitir, entregar, verificar y revocar.
Lista de comprobación del aprovisionamiento
- Credencial única por dispositivo, nunca una contraseña para toda la flota.
- Secretos generados o emitidos de forma centralizada, no inventados por los ingenieros de firmware.
- Identidad de bootstrap limitada exclusivamente al aprovisionamiento, con reclamación única y una lista de permitidos.
- Credenciales guardadas en almacenamiento cifrado o en un elemento seguro.
- TLS con verificación de certificado en todas las conexiones, incluida la llamada de aprovisionamiento.
- Inventario que asocia número de serie con client ID, sin secretos en texto claro.
- Un camino probado de reaprovisionamiento y rotación de credenciales.
- Backoff ante fallos de autenticación; ConnectMQ bloquea las IP tras varios inicios de sesión fallidos.
Planificar capacidad y entornos
El aprovisionamiento interactúa con los límites del plan. El plan Serverless (Free) permite hasta 25 conexiones, suficiente para un piloto; Serverless (Paid) llega hasta 1.000 conexiones, y los planes Dedicated o BYOC se adaptan a flotas más grandes o reguladas. Mantén brokers separados para desarrollo, preproducción y producción, de modo que los dispositivos de prueba nunca tengan credenciales de producción, y usa el servidor MQTT público gratuito solo para experimentos y prototipos con datos no sensibles, nunca para producción.
Empieza con ConnectMQ
Aprovisiona tus primeros dispositivos contra un broker MQTT en la nube con TLS, aislamiento de tenants y client IDs vinculados a las credenciales emitidas. Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito.
Preguntas frecuentes
¿Qué es el aprovisionamiento seguro de dispositivos IoT?
Es el proceso de dar a cada dispositivo una identidad y unas credenciales únicas, entregarlas sin exponerlas y registrarlas para poder rastrearlas y revocarlas más adelante.
¿Qué es un claim certificate?
Un claim certificate es una identidad limitada, a menudo compartida por lote, cuyo único permiso es solicitar una credencial única de dispositivo a un servicio de aprovisionamiento en el primer arranque.
¿Debo incrustar credenciales MQTT en las imágenes de firmware?
No. Una imagen de firmware se copia muchas veces y suele ser fácil de extraer. En su lugar, escribe credenciales únicas en el almacenamiento protegido de cada dispositivo.
¿ConnectMQ ofrece un servicio de aprovisionamiento de dispositivos?
No. Emites las credenciales en el portal de ConnectMQ y las entregas con tu propio proceso de fábrica o de bootstrap, como se muestra más arriba.



