EmbeddedEra EmbeddedEra

← Notas desde el banco de trabajo.

Aprovisionamiento BLE para un dispositivo sin pantalla

19 sept 2026 firmwaresecurity Traducido del original en inglés con ayuda de IA. Aún no ha sido revisado por una persona.

Leer el original en inglés ›

El producto tiene un botón, un LED y ninguna forma de escribir. El cliente tiene que cargarle el nombre y la contraseña de su Wi-Fi doméstico antes de que sirva para algo. En el banco, con un kit de desarrollo y una app BLE genérica, esto funciona la primera tarde. Luego se topa con un teléfono que muestra un diálogo de emparejamiento cada vez, un router con dos bandas bajo el mismo nombre y una contraseña mal escrita a las 9 p.m. por alguien que nunca leerá un manual.

Las mismas preguntas aparecen una y otra vez en foros de fabricantes y rastreadores de incidencias, y muchos de los hilos siguen sin respuesta: por qué iOS empareja y se queja al mismo tiempo, por qué un dispositivo aparece en un teléfono Android y en otro no, si «Just Works» es suficiente. Esta nota cubre las decisiones que importan.

Parte de un protocolo existente

No diseñes tu propio servicio GATT para esto. Ya existen tres opciones mantenidas:

  • ESP-IDF unified provisioning para partes de Espressif. Soporta los transportes BLE y SoftAP y tres esquemas de seguridad, descritos más abajo.
  • Improv Wi-Fi, un estándar abierto de la comunidad de ESPHome y Home Assistant. Corre sobre BLE o serial, y ambos se pueden manejar desde un navegador. Define cuatro estados (autorización requerida, autorizado, aprovisionando, aprovisionado) y un conjunto pequeño de comandos, entre ellos escanear y enviar credenciales.
  • Wi-Fi provisioning over BLE de Nordic, una muestra y un servicio en el nRF Connect SDK, para productos construidos con las partes Wi-Fi de Nordic.

Elijas la que elijas, lee qué protege y qué deja a tu cargo. La especificación de Improv trata la autorización como opcional pero recomendada, y la condiciona a una acción física en el dispositivo. Es una buena idea, pero activarla es tu trabajo.

BLE no es el único transporte. El aprovisionamiento SoftAP, donde el dispositivo se convierte brevemente en su propio punto de acceso, es el más interoperable. Pero el teléfono tiene que salir de la red del cliente para unirse a él, y la documentación de Espressif señala que iOS no tiene una API nativa para descubrir y unirse a ese punto de acceso, así que el usuario termina en los ajustes del sistema. BLE ofrece descubrimiento nativo en ambas plataformas. Espressif también cita unos 110 KB de memoria en tiempo de ejecución para su transporte BLE, algo que importa en una parte pequeña. Si el producto tiene un puerto USB, también vale la pena tener una ruta de aprovisionamiento serial.

Qué protege y qué no protege el emparejamiento

BLE ofrece cuatro métodos de emparejamiento: Just Works, Numeric Comparison, Passkey Entry y fuera de banda. Numeric Comparison necesita una pantalla y una entrada de sí/no en ambos lados. Passkey Entry necesita una pantalla de un lado y un teclado del otro. Un dispositivo con un botón y un LED no tiene ninguna de las dos cosas, así que recurre a Just Works, a menos que tenga un canal fuera de banda como NFC.

Just Works con LE Secure Connections cifra el enlace, lo que detiene a un espía pasivo. No demuestra quién está del otro lado. Nada en el intercambio le permite al usuario confirmar que habla con su dispositivo, y un atacante activo dentro del alcance de radio puede colocarse en medio. La contraseña de Wi-Fi es lo que se envía por ese enlace.

Por eso hay que autenticar en la capa de aplicación. Las opciones realistas:

EnfoqueQué demuestraA qué prestar atención
Ventana de autorización física (pulsar un botón, tiempo límite)Alguien está junto al dispositivo en este momentoVentana corta y una forma clara de reabrirla
Secreto por dispositivo en la etiqueta o en un código QRLa persona tiene esta unidad en la manoCada unidad necesita su propio secreto
Solo Just WorksNada más allá del cifrado del enlaceAceptable para un juguete, difícil de defender para cualquier cosa en una red doméstica

El esquema 1 de Espressif admite una prueba de posesión, un secreto único por dispositivo que se ingresa en el cliente, y el esquema 2 usa SRP6a con una sal y un verificador por dispositivo generados con anticipación. El esquema 0 es sin cifrado, y el esquema 1 con una prueba nula es cifrado sin autenticación. Lee la configuración, porque la opción predeterminada más fácil de demostrar no es la que debe salir en el producto.

El secreto por dispositivo tiene una regla estricta: debe ser distinto en cada unidad. Un secreto compilado dentro de la imagen de firmware es un solo secreto para toda la línea de productos, y cualquiera puede extraerlo de una actualización descargada. Genéralo en producción, prográmalo junto con el firmware e imprime la etiqueta a partir del mismo registro. Eso hace que el paso de prueba de fin de línea sea el lugar natural para esto, y significa que el fixture y la impresora de etiquetas deben ponerse de acuerdo sobre el origen del secreto antes de la primera corrida de producción, no después.

Combina las dos. Un botón que abre la ventana más un secreto por dispositivo que autentica la sesión cubren los casos que cada uno deja pasar por separado.

El teléfono es la mitad de tu producto

iOS. El emparejamiento no lo maneja la app. Los desarrolladores reportan que el sistema lo inicia cuando la app toca una característica que requiere cifrado, así que el lugar de tu tabla GATT donde pones el requisito de seguridad decide cuándo aparece el diálogo. Los mismos reportes describen el diálogo regresando en cada conexión, el emparejamiento fallando en el periférico mientras iOS registra un enlace exitoso, y enlaces perdidos después de que el teléfono rota su dirección privada. Algunos de esos hilos no tienen resolución. Tómalos como evidencia de que el bonding es una comodidad, no algo de lo que el aprovisionamiento pueda depender.

La regla práctica: haz que la sesión de aprovisionamiento funcione sin bond. Establece tu sesión de capa de aplicación en cada conexión. Si el bond sobrevive, bien. Si no, nada se rompe.

iOS 18 agregó AccessorySetupKit, que muestra un selector del sistema para tu accesorio y maneja el paso de descubrimiento y emparejamiento sin que la app pida permiso de Bluetooth. Requiere iOS 18 o posterior, el filtro de descubrimiento vive en el Info.plist de la app y no puede cambiar en tiempo de ejecución, y la app sigue comunicándose con el dispositivo a través de CoreBluetooth después. Vale la pena adoptarlo en una app nueva. No reemplaza la ruta anterior para los clientes con versiones más viejas de iOS.

Android. A partir de Android 12, escanear requiere el permiso de tiempo de ejecución BLUETOOTH_SCAN y conectarse requiere BLUETOOTH_CONNECT. Si la app declara que nunca usa el escaneo para derivar la ubicación, el sistema filtra algunos resultados, lo cual está bien para una app de aprovisionamiento pero importa si tu dispositivo anuncia de una manera inusual. Un dispositivo que aparece en el teléfono del desarrollador y no en el de un cliente suele ser un problema de permisos o del formato de advertising, no un problema de radio.

Prueba contra una matriz real: dos o tres iPhones con distintas versiones de iOS y teléfonos Android de más de un fabricante, incluido uno de hace unos años. Los emuladores no pueden hacer esto.

Diseña primero las rutas de falla

La mayor parte de la carga de soporte está en las rutas que nadie demostró.

Contraseña incorrecta. El dispositivo lo intenta, falla y tiene que decirlo. El conjunto de errores de Improv tiene un solo código de «no se pudo conectar», así que si quieres que la app distinga una contraseña incorrecta de una red fuera de alcance, tienes que transportar ese detalle tú mismo. Luego regresa a un estado en el que el usuario pueda intentarlo de nuevo, sin necesidad de apagar y encender.

Banda incompatible. La lista de redes muestra lo que ve la radio del dispositivo, no lo que ve el teléfono. Muchas partes Wi-Fi de bajo costo son solo de 2.4 GHz. Un cliente cuyo teléfono está en una red de 5 GHz buscará algo que no está en la lista. Dilo en la app.

Tiempos de espera. Una ventana de aprovisionamiento abierta debe cerrarse: Improv sugiere alrededor de un minuto para la autorización. El advertising también cuesta batería en un producto que funciona con batería, así que ponle un límite y define qué hace mantener presionado el botón para reabrirla.

Reaprovisionamiento. La gente cambia de router. Decide cómo se reemplazan o se borran las credenciales almacenadas, y qué elimina un restablecimiento de fábrica. Las credenciales en la flash del chip son tan privadas como la protección de lectura del chip, así que actívala en las partes de producción.

Ruta de actualización. Un dispositivo que acepta credenciales Wi-Fi normalmente también aceptará firmware, y ahí se aplican las mismas preguntas de recuperación y reversión. Asegúrate de que la autorización de aprovisionamiento y la autorización de actualización sean decisiones separadas, y de que ambas estén documentadas.

Cada una de estas es un comportamiento del firmware que puedes especificar en papel antes de escribir código, y cada una es más barata de especificar que de corregir después de la primera tanda de devoluciones.

Cómo lo manejamos

Partimos de la pila de aprovisionamiento del fabricante del chip, agregamos el secreto por dispositivo en la prueba de producción y probamos el flujo con teléfonos y routers reales antes de que salga al mercado. Si quieres que esto se diseñe dentro de un producto, envíanos el MCU o módulo de radio, las versiones de teléfono y sistema operativo que debes soportar y qué tendrá en la mano el cliente cuando lo configure.

¿Construyes un producto BLE que debe emparejarse sin pantalla? Escribimos el firmware de aprovisionamiento y la app que se comunica con él.

NOTAS DE INGENIERÍA

Una nota a la semana sobre diseño de PCB, firmware y cómo se construye hardware. Sin correos de ventas.

Doble confirmación. Puedes darte de baja con un clic.