Как разрешить клиентам саморегистрацию по HTTP, используя какой-нибудь тип открытого ключа? - PullRequest
1 голос
/ 28 июля 2011

Я работаю над созданием небольших ретрансляционных станций из крошечных встроенных коробок Linux.К ним подключены некоторые датчики, которые передают данные обратно на сервер через HTTP POST.Прямо сейчас сервер просто принимает их сообщение вместе с уникальным идентификатором (MAC-адрес eth0).

Я хочу расширить это, чтобы включить некоторый тип безопасности.Я хочу иметь возможность развертывать эти маленькие устройства с минимальной конфигурацией.Я хотел бы скопировать базовую прошивку на устройство, подключить их в поле, и они самостоятельно регистрируются.Когда они подключаются в первый раз, я бы хотел, чтобы сервер и устройство провели согласование, где я могу сохранить отпечаток пальца.Последующие запросы я мог бы затем аутентифицировать / проверить устройство с использованием этого отпечатка пальца.

Таким образом, как только устройство регистрируется со своим уникальным идентификатором, я могу быть уверен, что все данные с этого идентификатора поступают с одного устройства.Если устройство-ружье или набор устройств регистрируются, я просто удаляю их (я сохраняю IP-адреса, чтобы удалить их по неизвестным диапазонам и заблокировать их).

Мой вопрос: каков наилучший способ сделать это?Я вспоминаю идею «отпечатков пальцев» SSH, когда при первом подключении к серверу вы получаете отпечаток сервера.Если в будущем запрос выдаст другой отпечаток, вы получите огромное предупреждение, и вам придется вручную удалить отпечаток из вашего файла author_keys, если ключи сервера действительно были восстановлены (например, вы выполнили переустановку без сохранения старых ключей SSH).

Что-то подобное возможно с HTTP, возможно, избегая необходимости использовать предварительные ключи?

Если это имеет значение, клиенты работают на Python2, а сервер, к которому они подключаются, написан в основном на Scala на Tomcat.,

1 Ответ

1 голос
/ 28 июля 2011

По сути, все, что вам нужно сделать, это сообщить серверу открытый ключ, а затем подписать все ваши сообщения им.Если вам не нужны предварительные общие ключи, сервер не может быть уверен, что кто-то, кто регистрируется, на самом деле является одним из ваших устройств.Однако вы все еще можете проверить, что сообщение пришло с того же устройства, которое первоначально было зарегистрировано с этим идентификатором.

Процесс в основном происходит следующим образом:

  1. Клиент генерирует новую пару ключей (например, пара открытых / закрытых ключей RSA.
  2. Клиент регистрируется на сервере, отправляя свой открытый ключ.Сервер хранит этот открытый ключ.
  3. Когда клиент отправляет сообщение, он генерирует подпись своего сообщения, которое он прикрепляет к сообщению.Когда сервер получает сообщение, он проверяет подпись, чтобы убедиться, что сообщение было отправлено кем-то, имеющим соответствующий закрытый ключ.

Код для этого в PyCrypto выглядит примерно так:this:

Генерация пары ключей

from Crypto.PublicKey import RSA
key = RSA.generate(2048)
private_key = key.exportKey()
public_key = key.publickey().exportKey()
# private_key is a string suitable for storing on disk for retrieval later
# public_key is a string suitable for sending to the server
# The server should store this along with the client ID for verification

Генерация подписи

from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
key = RSA.importKey(private_key)
# where private_key is read from wherever you stored it previously
digest = SHA.new(message).digest()
signature = key.sign(digest, None)
# attach signature to the message however you wish

Сервер должен загрузить открытый ключ, как он был ранее сохранен, и использовать команду "verify"метод, предоставляемый Scala / Java crypto API, который вы используете, и принимайте сообщение только в случае успеха.

Важно понимать предостережения каждого подхода, поскольку различные методы защищают только от определенных типов атак.Например, описанный выше подход не защищает от «повторной атаки», при которой злоумышленник записывает сообщение с определенным значением, а затем повторно передает его на сервер в более позднее время.Одним из способов защиты от этого было бы включение метки времени в сообщение, которое хэшируется;другое - использовать должным образом зашифрованный транспорт (например, SSL / TLS).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...