2012-05-12 4 views
0

Я разрабатываю протокол для беспроводной связи между двумя микроконтроллерами с использованием модема 433 МГц, который может отправлять последовательные данные в необработанном формате (если хотите, обычный текст). Я знаю, что это больше похоже на электронный вопрос, но моя проблема заключается в кодировании, позвольте мне объяснить.Рекомендации по защите протоколов эфирного вещания

Пусть говорят, что блок один послать эту команду «0x001/0x010/light1/ON» (это обычный текст) к блоку 2, первый блок 1 название, второе название блока 2, третий привод и последнее действие. Все нормально и работает, НО Я хочу дать системе немного уровня безопасности, потому что, если кто-то слушает эту частоту с помощью техники, такой как «men-in-the-middle», можно легко скопировать команду и отправить ее в любое время хочет.

Я думал о том, криптование сообщения, передаваемые по воздуху, но опять же это не будет защищать систему от того же самого типа атаки, скажем, зашифровать сообщение, используя что-то вроде MD5, я передам что-то вроде «767b79ebb8061054d3ad1eaef428b469 «, злоумышленнику просто нужно скопировать эту строку и отправить ее для достижения того же результата.

Так как я могу это решить? Примите во внимание, что я не контролирую ядерный реактор, поэтому мне не нужен очень высокий уровень безопасности.

ответ

2

Я предполагаю, что каждый узел «знает» узлы, из которых предполагается принимать команды: в этом случае у получающего узла есть (простой) ключ для каждого узла, из которого он будет принимать команды, а затем добавить три поля в протокол:

  • соли (случайное число, созданное отправитель)
  • порядковый номер
  • поля аутентификации

и отправитель и получатель магазин последнего использование d для отношения tx-> rx, отправитель увеличивает его с каждой командой.

И отправитель и получатель создать хэш (SHA1?) Конкатенации SequenceNumber+Command+SequenceNumber+salt+nodekey

Edit:nodekey IST в отправляющего узла ключа

Отправитель посылает это как поле аутентификации, приемник проверяет его на поле аутентификации и принимает только команду, если порядковый номер больше, чем порядковый номер LRU, а поле проверки проверяет OK.

Это защищает от повторной атаки, так как это предполагает повторное использование порядкового номера.

Edit:

Существует обеспокоенность в комментариях о потере synchronity в последовательности чисел, но предложенное решение resiliant против этого: Только отправитель будет когда-либо увеличить SN, и приемник будет принимать все SN выше, чем последние. Потеря сообщения вызовет SN-прыжок, но он все равно будет принят как выше LRU.

+1

Я думаю, что важно рассмотреть потерю/повреждение данных, что может привести к тому, что порядковые номера будут синхронизироваться с обоих концов. –

+0

@Alex Я думал об этом – DomingoSL

+0

@Alex обновил мой ответ - я действительно рассматривал потерю сообщений –

-1

Вы должны использовать какое-то шифрование, которое зависит от ключа. Разумеется, ключ, вероятно, должен быть определен каким-то образом, что оба контроллера могут синхронизироваться - возможно, некоторые средства использования времени суток будут достаточными. Что-то вроде функции PHP time(), округленная до ближайшей сотни. Каждый контроллер, когда он получает сигнал, может проверять текущую округленную временную метку и предыдущую, поэтому, если злоумышленник получил зашифрованный сигнал, он будет использоваться повторно только в течение максимум 200 секунд. В зависимости от времени, которое требуется для передачи каждого сигнала и необходимого уровня безопасности (и, возможно, как часто вы можете уйти с пропущенным сигналом), вы можете округлить до десяти или пяти секунд. С некоторыми псевдо-кодом (округление до десяти):

Sending:

signal=encrypt(outgoing, round(time, 10)) 
sendSignal(signal) 

Принимающий:

signal=decrypt(incoming, round(time, 10)) 
if (invalid(signal)) {signal=decrypt(incoming, round(time, 10)-10)} 
interpretSignal(signal) 

Вы бы, как указано во второй строке, нужно каким-то образом определения, является ли дешифрованный сигнал действительным.

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

1

скажем зашифровать сообщение, используя что-то вроде MD5, я передавать что-то вроде «767b79ebb8061054d3ad1eaef428b469»,

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

злоумышленнику просто нужно скопировать эту строку и отправить ее для достижения того же результата.

Это актуальная проблема и относится к категории Replay Attack. Есть много способов решить эту проблему, но для этого требуется довольно много усилий, чтобы перепроектировать как ваши передатчики, так и приемники.

0

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

Если у вас есть MD5, доступный на вашем контроллере, я бы использовал метод Eugen Rieck, за исключением того, что я просто сказал бы, что вы можете использовать только каждый ключ каждый раз, когда каждый скажет 10 дней или что-то в зависимости от того, сколько данных вы отправляете.

Это делает его уже более безопасным, и, за исключением случаев, когда они выполняют длительное прослушивание, они не смогут использовать ваши команды.

Имейте в виду, что это что-то вроде Security through obscurity, и если они нападающие знают, что у него есть только 10-дневное охлаждение, это не сработает.

Если у вас есть функции шифрования и время работы на вашем устройстве, я бы просто использовал базовую функцию шифрования с текущим временем.

Смежные вопросы