Espruino:Примеры/Безопасность и контроль доступа при использовании BLE на Puck.js: различия между версиями
Myagkij (обсуждение | вклад) (Новая страница: «{{Espruino/Панель перехода}} {{Перевод от Сubewriter}} {{Myagkij-редактор}} =<ref>[ www.espruino.com - ]</ref>= <syntaxhighligh...») |
Myagkij (обсуждение | вклад) Нет описания правки |
||
Строка 3: | Строка 3: | ||
{{Myagkij-редактор}} | {{Myagkij-редактор}} | ||
=<ref>[ www.espruino.com - ]</ref>= | =Безопасность и контроль доступа при использовании BLE на Puck.js<ref>[https://www.espruino.com/BLE+Security www.espruino.com - Bluetooth LE Security and Access Control]</ref>= | ||
В момент, когда вы вынете пластиковый разделитель из батарейного отсека [[Puck.js]], устройство тут же запустится, после чего к нему можно будет подключиться и программировать. | |||
<syntaxhighlight lang=" | Как и прочие подобные устройства для разработки проектов, [[Puck.js]] создан с прицелом на то, чтобы вы могли начать пользоваться им как можно быстрее – без необходимости вводить пароли. | ||
Но как только вы возьмётесь за более-менее серьёзные проекты, то наверняка захотите поставить защиту, чтобы [[Puck.js]] не мог перепрограммировать кто-то другой. | |||
'''Примечание:''' Если в [[Puck.js]] не будет настроена привязка (см. раздел «Привязка и белый список» ниже), Bluetooth-коммуникация будет незашифрованной. В этом случае будьте готовы к тому, что рядом может оказаться злоумышленник с устройством для прослушки Bluetooth-связи, который сможет просматривать всё, что было записано и загружено на Puck.js. | |||
Итак, как же защитить Puck.js? Есть несколько вариантов. | |||
== Запретите подключаться к Puck.js == | |||
При помощи функции NRF.setAdvertising() вы можете разрешить Puck.js рассылать Bluetooth-объявления, но также сделать так, чтобы к нему не мог подключиться ни один ПК: | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
NRF.setAdvertising({}, { connectable:false }); | |||
</syntaxhighlight> | |||
== Поставьте пароль при помощи E.setPassword("пароль") == | |||
[http://wikihandbk.com/wiki/Espruino:Справочник_по_API/Класс_E/setPassword() См. тут]. В результате UART продолжить работать, и любой компьютер по-прежнему сможет подключиться к Puck.js, но теперь каждый, кто захочет получить доступ к консоли Espruino, должен будет ввести пароль. | |||
Это неидеальный вариант, так как к Puck.js по-прежнему сможет подключиться любой – он просто не получит доступа к JavaScript-консоли. | |||
== Спрячьте консоль == | |||
При помощи команды LoopbackA.setConsole(true) можно принудительно поместить JavaScript-консоль в [http://wikihandbk.com/wiki/Espruino:Справочник_по_API/Глобальные_методы,_переменные_и_объекты/Объект_LoopBackA Loopback]. | |||
В результате консоль будет доступна только через чтение и запись в переменную LoopbackB. Если кто-то подключится к Puck.js, у него по-прежнему будет доступ к UART, но он ничего не сможет сделать. | |||
Всё, что будет записываться в Bluetooth UART, по-прежнему будет доступно в переменной Bluetooth через Bluetooth.on('data', function(data) { ... }), и вы также сможете отправлять ответы при помощи Bluetooth.write(...). | |||
Примечание: Вы больше не сможете программировать Puck.js, пока не выполните сброс или не вызовите Bluetooth.setConsole(). | |||
== Отключение при обнаружении незнакомого адреса (белый список) == | |||
Вы можете легко подцепиться к событию connect, а затем принудительно отключиться, если обнаружится, что подключение инициировано незнакомым адресом. | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
NRF.on('connect',function(addr) { | |||
if (addr!="69:2d:94:d0:9d:97 public") | |||
NRF.disconnect(); | |||
}); | |||
</syntaxhighlight> | |||
У других Puck.js адрес обычно имеет формат "aa:bb:cc:dd:ee:ff random", а у ПК и телефонов это, как правило, что-то вроде "aa:bb:cc:dd:ee:ff public". | |||
Чтобы выяснить, какой MAC-адрес добавить в белый список, загрузите вот этот код: | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
devices = []; | |||
NRF.on('connect',function(addr) { | |||
devices.push(addr); | |||
}); | |||
// теперь подключитесь несколько раз | |||
// и посмотрите, что находится в «devices» в левой части IDE | |||
</syntaxhighlight> | |||
Примечание: Новые версии Android умеют делать «рандомизацию MAC-адреса» – это позволяет им при каждом новом подключении использовать случайный MAC-адрес. В таком случае этот метод не подойдёт. | |||
Примечание: MAC-адреса можно менять, так что этот метод надёжен не на 100%. Впрочем, шансы на то, что кто-то угадает правильный MAC-адрес – не находясь при этом в области подключения в момент, когда соединение активно, чтобы иметь возможность его прослушать – крайне малы. | |||
== Отключите BLE UART == | |||
Если вы не хотите, чтобы у пользователя был доступ к BLE UART, рекомендуем полностью его отключить при помощи [http://wikihandbk.com/wiki/Espruino:Справочник_по_API/Класс_NRF/setServices() NRF.setServices()]. | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
NRF.setServices(undefined, { | |||
uart : false | |||
}); | |||
</syntaxhighlight> | |||
Это полностью отключит сервис UART, в результате чего Puck.js нельзя будет перепрограммировать (пока не выполнить сброс). | |||
Если снова вызвать NRF.setServices() с настройкой uart:true, это возобновит работу UART. К примеру, код ниже выключает и включает UART (а также мигает красным и зелёным светодиодами) при нажатии на кнопку. | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
var locked = true; | |||
NRF.setServices(undefined,{uart:!locked}); | |||
setWatch(function() { | |||
locked = !locked; | |||
digitalPulse(locked?LED1:LED2,1,100); | |||
NRF.setServices(undefined,{uart:!locked}); | |||
}, BTN, {repeat:true, edge:"rising", debounce:50}); | |||
</syntaxhighlight> | |||
== Отключите Bluetooth == | |||
Вы можете включить и выключить Bluetooth при помощи функций [http://wikihandbk.com/wiki/Espruino:Справочник_по_API/Класс_NRF/sleep() NRF.sleep()] и [http://wikihandbk.com/wiki/Espruino:Справочник_по_API/Класс_NRF/wake() NRF.wake()]. | |||
Это остановит рассылку Bluetooth-объявлений, с помощью которых Puck.js объявляет о своём присутствии, а также сделает так, чтобы к Puck.js нельзя было подключиться. Это также увеличит продолжительность работы батареи. | |||
Код ниже мигает красным и зелёным светодиодами, а также включает и выключает Bluetooth. | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
var locked = false; | |||
setWatch(function() { | |||
locked = !locked; | |||
digitalPulse(locked?LED1:LED2,1,100); | |||
if (locked) NRF.sleep(); | |||
else NRF.wake(); | |||
}, BTN, {repeat:true, edge:"rising", debounce:50}); | |||
</syntaxhighlight> | |||
== Привязка / занесение в белый список == | |||
В версии Espruino 1v92 в Puck.js была реализована функция привязки. Будучи привязанными, устройства могут создавать безопасное подключение друг к другу. | |||
Puck.js принимает и безопасные, и небезопасные подключения – решение о том, запускать ли процедуру привязки или нет, остаётся за подключающимся устройством. Если вызвать функцию NRF.setWhitelist(true), то следующее устройство, которое будет привязано к Puck.js, будет также добавлено в белый список. В результате устройства, которых нет в белом списке, к Puck.js подключиться не смогут, пока он не будет перезапущен (для этого нужно зажать кнопку). | |||
Сам Puck.js, подключаясь к другому устройству, тоже может инициировать процедуру привязки – это делается с помощью метода startBonding(). Кроме того, подключившись, при помощи функции [http://wikihandbk.com/wiki/Espruino:Справочник_по_API/Класс_BluetoothRemoteGATTServer/getSecurityStatus() getSecurityStatus() можно узнать настройки безопасности соединения]. | |||
== Сопряжение с помощью ключа доступа (пароля) == | |||
В версии Espruino 2v02 (и в самых свежих, но нестабильных билдах) можно задать статический ключ доступа (пароль). | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
NRF.setSecurity({passkey:"123456", mitm:1, display:1}); | |||
</syntaxhighlight> | |||
При попытке подключения центральное устройство запросит ключ доступа (пароль), и если он окажется неправильным, подключение установлено не будет. | |||
Когда Espruino работает в режиме центрального устройства, которому нужно подключиться к другому устройству, ключ доступа можно ввести при помощи события BluetoothDevice.passkeyRequest и метода BluetoothDevice.sendPasskey() но при этом в NRF.setSecurity должно быть задано keyboard:1). | |||
== Отключите команды dump() и E.dumpStr() == | |||
Благодаря этим командам тот, у кого есть доступ к консоли Espruino, может легко выгрузить программный код, хранящийся на устройстве. | |||
Их можно отключить при помощи global.dump=function(){};E.dumpStr=function(){};, но полную защиту это не гарантирует, потому что, выполнив некоторые манипуляции, их можно снова включить. Кроме того, если злоумышленник будет иметь доступ к консоли Espruino, то сможет прочесть состояние интерпретатора даже без этих команд. Другими словами, вы можете реконструировать большую часть кода, даже не используя dump(). | |||
Если вас беспокоит то, что кто-то может прочесть ваш код, лучше вообще отключите консоль (см. выше). | |||
=См.также= | =См.также= |
Версия от 15:34, 6 марта 2021
Безопасность и контроль доступа при использовании BLE на Puck.js[1]
В момент, когда вы вынете пластиковый разделитель из батарейного отсека Puck.js, устройство тут же запустится, после чего к нему можно будет подключиться и программировать.
Как и прочие подобные устройства для разработки проектов, Puck.js создан с прицелом на то, чтобы вы могли начать пользоваться им как можно быстрее – без необходимости вводить пароли.
Но как только вы возьмётесь за более-менее серьёзные проекты, то наверняка захотите поставить защиту, чтобы Puck.js не мог перепрограммировать кто-то другой.
Примечание: Если в Puck.js не будет настроена привязка (см. раздел «Привязка и белый список» ниже), Bluetooth-коммуникация будет незашифрованной. В этом случае будьте готовы к тому, что рядом может оказаться злоумышленник с устройством для прослушки Bluetooth-связи, который сможет просматривать всё, что было записано и загружено на Puck.js.
Итак, как же защитить Puck.js? Есть несколько вариантов.
Запретите подключаться к Puck.js
При помощи функции NRF.setAdvertising() вы можете разрешить Puck.js рассылать Bluetooth-объявления, но также сделать так, чтобы к нему не мог подключиться ни один ПК:
NRF.setAdvertising({}, { connectable:false });
Поставьте пароль при помощи E.setPassword("пароль")
См. тут. В результате UART продолжить работать, и любой компьютер по-прежнему сможет подключиться к Puck.js, но теперь каждый, кто захочет получить доступ к консоли Espruino, должен будет ввести пароль.
Это неидеальный вариант, так как к Puck.js по-прежнему сможет подключиться любой – он просто не получит доступа к JavaScript-консоли.
Спрячьте консоль
При помощи команды LoopbackA.setConsole(true) можно принудительно поместить JavaScript-консоль в Loopback.
В результате консоль будет доступна только через чтение и запись в переменную LoopbackB. Если кто-то подключится к Puck.js, у него по-прежнему будет доступ к UART, но он ничего не сможет сделать.
Всё, что будет записываться в Bluetooth UART, по-прежнему будет доступно в переменной Bluetooth через Bluetooth.on('data', function(data) { ... }), и вы также сможете отправлять ответы при помощи Bluetooth.write(...).
Примечание: Вы больше не сможете программировать Puck.js, пока не выполните сброс или не вызовите Bluetooth.setConsole().
Отключение при обнаружении незнакомого адреса (белый список)
Вы можете легко подцепиться к событию connect, а затем принудительно отключиться, если обнаружится, что подключение инициировано незнакомым адресом.
NRF.on('connect',function(addr) {
if (addr!="69:2d:94:d0:9d:97 public")
NRF.disconnect();
});
У других Puck.js адрес обычно имеет формат "aa:bb:cc:dd:ee:ff random", а у ПК и телефонов это, как правило, что-то вроде "aa:bb:cc:dd:ee:ff public".
Чтобы выяснить, какой MAC-адрес добавить в белый список, загрузите вот этот код:
devices = [];
NRF.on('connect',function(addr) {
devices.push(addr);
});
// теперь подключитесь несколько раз
// и посмотрите, что находится в «devices» в левой части IDE
Примечание: Новые версии Android умеют делать «рандомизацию MAC-адреса» – это позволяет им при каждом новом подключении использовать случайный MAC-адрес. В таком случае этот метод не подойдёт.
Примечание: MAC-адреса можно менять, так что этот метод надёжен не на 100%. Впрочем, шансы на то, что кто-то угадает правильный MAC-адрес – не находясь при этом в области подключения в момент, когда соединение активно, чтобы иметь возможность его прослушать – крайне малы.
Отключите BLE UART
Если вы не хотите, чтобы у пользователя был доступ к BLE UART, рекомендуем полностью его отключить при помощи NRF.setServices().
NRF.setServices(undefined, {
uart : false
});
Это полностью отключит сервис UART, в результате чего Puck.js нельзя будет перепрограммировать (пока не выполнить сброс).
Если снова вызвать NRF.setServices() с настройкой uart:true, это возобновит работу UART. К примеру, код ниже выключает и включает UART (а также мигает красным и зелёным светодиодами) при нажатии на кнопку.
var locked = true;
NRF.setServices(undefined,{uart:!locked});
setWatch(function() {
locked = !locked;
digitalPulse(locked?LED1:LED2,1,100);
NRF.setServices(undefined,{uart:!locked});
}, BTN, {repeat:true, edge:"rising", debounce:50});
Отключите Bluetooth
Вы можете включить и выключить Bluetooth при помощи функций NRF.sleep() и NRF.wake().
Это остановит рассылку Bluetooth-объявлений, с помощью которых Puck.js объявляет о своём присутствии, а также сделает так, чтобы к Puck.js нельзя было подключиться. Это также увеличит продолжительность работы батареи.
Код ниже мигает красным и зелёным светодиодами, а также включает и выключает Bluetooth.
var locked = false;
setWatch(function() {
locked = !locked;
digitalPulse(locked?LED1:LED2,1,100);
if (locked) NRF.sleep();
else NRF.wake();
}, BTN, {repeat:true, edge:"rising", debounce:50});
Привязка / занесение в белый список
В версии Espruino 1v92 в Puck.js была реализована функция привязки. Будучи привязанными, устройства могут создавать безопасное подключение друг к другу.
Puck.js принимает и безопасные, и небезопасные подключения – решение о том, запускать ли процедуру привязки или нет, остаётся за подключающимся устройством. Если вызвать функцию NRF.setWhitelist(true), то следующее устройство, которое будет привязано к Puck.js, будет также добавлено в белый список. В результате устройства, которых нет в белом списке, к Puck.js подключиться не смогут, пока он не будет перезапущен (для этого нужно зажать кнопку).
Сам Puck.js, подключаясь к другому устройству, тоже может инициировать процедуру привязки – это делается с помощью метода startBonding(). Кроме того, подключившись, при помощи функции getSecurityStatus() можно узнать настройки безопасности соединения.
Сопряжение с помощью ключа доступа (пароля)
В версии Espruino 2v02 (и в самых свежих, но нестабильных билдах) можно задать статический ключ доступа (пароль).
NRF.setSecurity({passkey:"123456", mitm:1, display:1});
При попытке подключения центральное устройство запросит ключ доступа (пароль), и если он окажется неправильным, подключение установлено не будет.
Когда Espruino работает в режиме центрального устройства, которому нужно подключиться к другому устройству, ключ доступа можно ввести при помощи события BluetoothDevice.passkeyRequest и метода BluetoothDevice.sendPasskey() но при этом в NRF.setSecurity должно быть задано keyboard:1).
Отключите команды dump() и E.dumpStr()
Благодаря этим командам тот, у кого есть доступ к консоли Espruino, может легко выгрузить программный код, хранящийся на устройстве.
Их можно отключить при помощи global.dump=function(){};E.dumpStr=function(){};, но полную защиту это не гарантирует, потому что, выполнив некоторые манипуляции, их можно снова включить. Кроме того, если злоумышленник будет иметь доступ к консоли Espruino, то сможет прочесть состояние интерпретатора даже без этих команд. Другими словами, вы можете реконструировать большую часть кода, даже не используя dump().
Если вас беспокоит то, что кто-то может прочесть ваш код, лучше вообще отключите консоль (см. выше).
См.также
Внешние ссылки