My Internet of Things: Guest Castle (Parte 2)

Hola gt ¡Todo con la venida y el pasado!
Continúo la historia de cómo conecté la cerradura de la puerta a Internet. Haga clic aquí .
Muchas gracias a todos por los comentarios. Realmente hay soluciones listas para usar, pero también hay una serie de matices que no me permitieron usarlas. Un apartamento todavía no es un hotel, por lo que descartamos los castillos especializados de hotel de inmediato. Cerraduras de llave, antenas para NFC, para no asustar a los vecinos, tampoco lo consideramos. Tampoco se puede usar ninguna tarjeta, ficha u otro medio físico, se entiende que no hay forma de transferirlos a un invitado antes de que abra la puerta.
Kevo, August o Lockitron no pudieron ser utilizados, porque se basan en el tipo de cerradura americana (cerrojo), que no está muy bien instalado en una puerta de acero de 65-70 mm de espesor. Nuestra elección es el CISA electromecánico para puertas blindadas, con un precio de alrededor de 500 euros (aún no comprado, porque es caro).
Y lo más importante, quiero hacer algo con mis propias manos, no ser egoísta por el bien de las corrientes de hobby.


Permítame recordarle que el controlador de bloqueo está ubicado detrás de NAT en la red doméstica local y, por lo tanto, no tiene sentido crear un servidor web en Arduin; no hay forma de acceder a él desde Internet. El servidor está escrito en Python usando el marco Twisted, se ejecuta en Linux en otro lugar donde hay una dirección IP real, y el controlador se conecta a él y espera los comandos.

Ahora quiero hablar sobre la lógica del trabajo y la criptografía.
No encontré algo que encriptara el tráfico de Arduina, porque las comunicaciones del castillo y el servidor pasarán por canales abiertos con tráfico sin encriptar.
En el primer prototipo, usé MD5, ahora lo cambié a SHA-1, aquí en esta biblioteca Cryptosuite . Consume menos memoria y ya hay una función HMAC preparada.
La clave es una contraseña de hasta 30 caracteres ASCII, almacenada en la memoria EEPROM del controlador.
En el primer prototipo, la misma contraseña se almacenó explícitamente en el servidor, lo que por supuesto no es seguridad. El segundo prototipo requería dos contraseñas. El primero es autenticar el bloqueo cuando se conecta al servidor, no puede abrir el bloqueo con esta contraseña, es necesario para que solo los bloqueos correctos puedan conectarse al servidor.
El bloqueo se conecta al servidor y, en primer lugar, le dice su identificador. El servidor verifica en la base de datos si existe dicho bloqueo, y si lo hay, envía una secuencia ASCII generada aleatoriamente en respuesta. El candado lo "firma" con una contraseña y devuelve el hash. El servidor compara el hash recibido con lo que calculó por sí mismo, y si coinciden, autorizará al controlador conectado como un "bloqueo".
De lo contrario, la conexión se restablece.
La segunda contraseña ya es una clave digital; no está almacenada en el servidor.
Funciona de la siguiente manera: la aplicación del usuario llama a través de la función SOAP en el servidor, indica la ID de la cerradura y el comando que desea enviarle. Como resultado, la función devuelve la ID de solicitud. El servidor reenvía este comando al controlador, el controlador envía una secuencia ASCII generada aleatoriamente en respuesta y espera la respuesta "correcta" durante un par de segundos. A continuación, la aplicación de usuario debe obtenerla del servidor, a través del mismo SOAP mediante el ID de la solicitud, firmarla con una clave digital y enviarla de vuelta.
El controlador compara el hash recibido con el calculado por sí mismo y, si coinciden, ejecuta el comando recibido anteriormente, que se informa al servidor.
El tiempo para confirmar el comando está limitado a 2 segundos, si no se recibe respuesta durante este tiempo, el controlador ignora el comando recibido anteriormente. Si los hashes no coinciden, el comando también se ignora.
Por lo tanto, trato de protegerme del ataque "hombre en el medio", que es muy fácil de organizar en los cables de mi proveedor. La conexión allí es simple, no hay contraseñas ni certificados, es suficiente para cortar el par trenzado en el escudo, apretarlo en ambos lados, enchufarlo a la red desde el lado del apartamento con la dirección IP del servidor de comandos, emular el bloqueo en el otro extremo (también escribí un script para emulación en el pitón para la depuración) ), habiendo organizado un "cortafuegos" con escuchas telefónicas.
En este sentido, en mi opinión, el castillo resultó estar bastante protegido.
Incluso piratear el servidor de comandos y robar su base de datos con contraseñas para la autorización del bloqueo no causará muchos problemas, ya que no pueden abrir el bloqueo.
Solo queda tratar con los invitados. Estos son los requisitos No. 6-8 del primer artículo.
Los teclados, proxies, RFID y NFC no son una opción, lo anterior escribió por qué. Pero casi todos tienen un teléfono inteligente y todos los teléfonos inteligentes tienen Bluetooth, ¡la elección es obvia!

En el primer prototipo, un invitado estaba asociado con un único código de acceso. En la base de datos del servidor para este código se almacenaron la ID de la cerradura, la fecha y hora del comienzo y el final del acceso del invitado, bueno, un campo de texto para el nombre legible por el humano del invitado.
Un invitado se acerca a la cerradura, inicia una aplicación móvil en su teléfono inteligente, envía un código de acceso por Bluetooth al controlador, llega un mensaje del controlador al servidor que indica que un invitado se ha acercado a él con un cierto código de acceso. El servidor lo compara con la base de datos, y si el invitado correcto llegó en el momento correcto en el lugar correcto, envía el comando para abrir el bloqueo. De hecho, en lugar del código de acceso claro, el invitado enviará un hash HMAC firmado con un "sello temporal" (una representación de cadena del tiempo Unix dividido por 30 con la parte fraccional descartada). El servidor para la verificación realiza una solicitud a la base de datos con una selección de todos los códigos de acceso actualmente válidos para un bloqueo dado, luego lo itera y calcula un HMAC similar para ellos, si encuentra una coincidencia, envía un comando para abrir,Si la búsqueda de códigos de acceso finaliza antes de que se pueda encontrar una coincidencia, se envía una respuesta negativa al candado al intentar abrirlo.
El problema es que la clave digital para dicha autorización tenía que almacenarse en el servidor.
Tuve que complicar la autorización de "invitado" para el segundo prototipo. El código de acceso de invitado ahora consta de dos claves, llamémoslas "servidor" y "privado". El servidor es necesario para establecer una cuenta de invitado en el servidor y privado para abrir el bloqueo. La sala del servidor se almacenará explícitamente en el servidor, y desde la privada solo habrá un hash, pero no uno simple, sino un HMAC con una llave digital para la cerradura.
Ahora la sesión de autorización de invitado se ve así:
1. La aplicación de invitado envía la clave del "servidor" al controlador (como en el primer prototipo, su hash) y
2. El servidor la verifica de la misma manera, pero en lugar del comando abierto envía el hash de la clave privada.
3. El controlador compara el hash de la clave privada recibida del servidor con la calculada de forma independiente y, si coincide, se abre el bloqueo.
Por lo tanto, el servidor no almacena nada que pueda abrir el bloqueo. No funcionará generar el hash deseado sin conocer la clave digital.
El mismo Bluetooth también se utiliza para el acceso "maestro" sin Internet. El controlador recibe comandos a través de él, responde con un código único, que debe firmarse con la clave digital correcta durante 2 segundos.
A través de él, quiero hacer la configuración básica del controlador. El propietario presiona un botón especial en el controlador, después de lo cual comienza a aceptar un conjunto extendido de comandos, como configurar la ID de bloqueo, las claves secretas, la dirección del puerto del servidor, la configuración de red, etc. Pero en Adruin se acabó la memoria y el boceto no encaja.
Al final, una breve demostración del trabajo.

Source: https://habr.com/ru/post/es382677/


All Articles