Minha Internet das Coisas: Guest Castle (Parte 2)

Oi GT! Tudo com a vinda e o passado!
Continuo a história de como conectei a fechadura da porta à Internet. Comece aqui .
Muito obrigado a todos pelos comentários. Realmente existem soluções prontas, mas também há várias nuances que não me permitiram usá-las. Como um apartamento ainda não é um hotel, descartamos os castelos especializados imediatamente. Fechaduras com chaves, antenas para NFC, para não assustar os vizinhos, também não consideramos. Nenhum cartão, token ou outro meio físico também pode ser usado; entende-se que não há como transferi-los para um hóspede antes que ele abra a porta.
Kevo, August ou Lockitron não puderam ser utilizados, porque eles são baseados no tipo americano de trava (trava), que não é muito bem instalada em uma porta de aço com 65 a 70 mm de espessura. Nossa escolha é o CISA eletromecânico para portas blindadas, ao preço de cerca de 500 euros (ainda não comprado, porque caro).
E o mais importante, quero fazer algo com minhas próprias mãos, para não ser egoísta por causa das correntes do hobby.


Deixe-me lembrá-lo de que o controlador de bloqueio está localizado atrás do NAT na rede doméstica local e, portanto, não faz sentido aumentar o servidor da web no Arduin, é impossível acessá-lo pela Internet. O servidor é escrito em Python usando a estrutura Twisted, é executado no Linux em outro local onde existe um endereço IP real, e o controlador se conecta a ele e aguarda comandos.

Agora eu quero falar sobre a lógica do trabalho e da criptografia.
Não encontrei algo que criptografasse o tráfego da Arduina, porque as comunicações do castelo e do servidor passarão por canais abertos com tráfego não criptografado.
No primeiro protótipo, usei o MD5, agora mudei para SHA-1, aqui nesta biblioteca Cryptosuite . Consome menos memória e já existe uma função HMAC pronta.
A chave é uma senha de até 30 caracteres ASCII, armazenada na memória EEPROM do controlador.
No primeiro protótipo, a mesma senha foi armazenada explicitamente no servidor, o que obviamente não é segurança. O segundo protótipo exigia duas senhas. O primeiro é autenticar o bloqueio ao conectar-se ao servidor; você não pode abrir o bloqueio com essa senha; é necessário para que apenas os bloqueios corretos possam se conectar ao servidor.
O bloqueio se conecta ao servidor e, antes de tudo, informa seu identificador. O servidor verifica no banco de dados se existe esse bloqueio e, se houver, envia uma sequência ASCII gerada aleatoriamente em resposta. A trava “assina” com uma senha e envia o hash de volta. O servidor compara o hash recebido com o que calculou por si próprio e, se corresponderem, autorizará o controlador conectado como um "bloqueio".
Caso contrário, a conexão é redefinida.
A segunda senha já é uma chave digital, não está armazenada no servidor.
Funciona da seguinte forma: o aplicativo do usuário chama pela função SOAP no servidor, indica o ID do bloqueio e o comando que ele deseja enviar. Como resultado, a função retorna o ID da solicitação. O servidor encaminha esse comando ao controlador, o controlador envia uma sequência ASCII gerada aleatoriamente em resposta e aguarda a resposta "correta" por alguns segundos. Em seguida, o aplicativo do usuário precisa obtê-lo do servidor, através do mesmo SOAP por ID da solicitação, assiná-lo com uma chave digital e enviá-lo de volta.
O controlador compara o hash recebido com o calculado por conta própria e, se corresponderem, executa o comando recebido anteriormente, que é relatado ao servidor.
O tempo para confirmar o comando é limitado a 2 segundos; se nenhuma resposta for recebida durante esse período, o controlador ignorará o comando recebido anteriormente. Se os hashes não corresponderem, o comando também será ignorado.
Assim, tento me proteger do ataque do “homem do meio”, que é muito fácil de organizar nos fios do meu provedor. A conexão é simples, sem senhas e certificados, basta cortar o par trançado no escudo, apertá-lo nos dois lados, conectá-lo à rede pelo lado do apartamento com o endereço IP do servidor de comando, emular a trava na outra extremidade (também escrevi um script para emulação no python para depuração ), tendo organizado um "firewall" com escutas telefônicas.
A este respeito, na minha opinião, o castelo mostrou-se bastante protegido.
Mesmo invadir o servidor de comando e roubar seu banco de dados com senhas para autorização pelo bloqueio não causará muitos problemas, porque eles não podem abrir o bloqueio.
Resta apenas lidar com os convidados. Estes são os requisitos nº 6-8 do primeiro artigo.
Teclados, proxies, RFID e NFC não são uma opção, o que foi mencionado acima. Mas quase todo mundo tem um smartphone e todos os smartphones têm Bluetooth, a escolha é óbvia!

No primeiro protótipo, um convidado foi associado a um único código de acesso. No banco de dados do servidor para esse código, foi armazenado o ID do bloqueio, a data e a hora do início e do final do acesso do convidado, bem, um campo de texto para o nome legível por humanos do convidado.
O hóspede chega ao castelo, lança o aplicativo móvel em seu smartphone, envia um código de acesso via Bluetooth ao controlador, uma mensagem chega do controlador ao servidor informando que um hóspede o abordou com esse código de acesso. O servidor verifica o banco de dados e, se o convidado correto chegou no momento certo e no lugar certo, envia o comando para abrir o bloqueio. De fato, em vez do código de acesso claro, o convidado enviará um hash HMAC assinado com um "carimbo temporário" (uma representação de sequência do tempo do Unix dividida por 30 com a parte fracionária descartada). O servidor para verificação faz uma solicitação ao banco de dados com uma seleção de todos os códigos de acesso atualmente válidos para um determinado bloqueio, itera e calcula um HMAC semelhante para eles, se encontrar uma correspondência, envia um comando para abrir,se a pesquisa de códigos de acesso terminar antes que uma correspondência seja encontrada, uma resposta negativa será enviada ao bloqueio na tentativa de abri-lo.
O problema é que a chave digital para tal autorização tinha que ser armazenada no servidor.
Eu tive que complicar a autorização de "convidado" para o segundo protótipo. O código de acesso do convidado agora consiste em duas chaves, vamos chamá-las de "servidor" e "privado". O servidor é necessário para estabelecer uma conta de convidado no servidor e privado para abrir o próprio bloqueio. A sala do servidor será armazenada explicitamente no servidor e a privada terá apenas um hash, mas não um simples, mas um HMAC com uma chave digital na fechadura.
Agora, a sessão de autorização de convidado é assim:
1. O aplicativo convidado envia a chave "server" para o controlador (como no primeiro protótipo, seu hash) e
2. O servidor verifica da mesma maneira, mas, em vez do comando open, envia o hash da chave privada
3. O controlador compara o hash da chave privada recebida do servidor com o calculado independentemente e, se corresponder, o bloqueio será aberto.
Portanto, o servidor não armazena nada que possa abrir o bloqueio. Não funcionará para gerar o hash desejado sem conhecer a chave digital.
O mesmo Bluetooth também é usado para acesso "principal" sem a Internet. O controlador recebe comandos através dele, responde com um código único, que deve ser assinado com a chave digital correta por 2 segundos.
Através dele, quero fazer as configurações básicas do controlador. O proprietário pressiona um botão especial no controlador, após o qual ele começa a aceitar um conjunto estendido de comandos, como definir o ID de bloqueio, chaves secretas, endereço da porta do servidor, configurações de rede etc. Mas em Adruin a memória acabou e o esboço não se encaixa.
No final, uma breve demonstração do trabalho.

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


All Articles