Digispark как хранитель паролей и передача данных на HID устройство.
- Войдите на сайт для отправки комментариев
Вот решил запилить аппаратный хранитель паролей. Для базы девайса использую Arduino Digispark.
На устройстве две кнопки: P0 - перебор ячеек, P2 - перебор хост/логин/пароль. Входы Р0 и Р2 замыкаются на землю.
Digispark подключается как обычная клавиатура. Далее алгоритм простой:
1. Ввод пин кода:
В любом текстовом редакторе (или любом EditControl) Digispark напишет запрос пин кода. Перебирая кнопками Р0 и Р2, мы вводим пин код. После чего нам доступен функционал логинов/паролей.
2. Ввод логин/пароль
При нажатии Р0 в строке браузера, или другого EditControl Digispark вводит адрес хоста. Далее кликаем на поле "логин" и нажимаем кнопку Р2 - появляется логин , переходим на поле "пароль" и опять нажимаем Р2 - вносится пароль.
Законченное устройство предполагается залочить фюзами и давать доступ к паролям только после ввода пин кода. При повторении не верных попыток, стирать данные паролей и логинов.
Потестил макетный вариант устройства - вроде все удобно.
Возникла проблема:
Хочется записывать парли и логины без перекомпиляции проекта. В стандартной библиотеке DigiKeyboard.h нету такой возможности. Переводить тип подключения как COM PORT/HID тоже не удалось из за конфликта библиотек да и не нравится мне этот вариант - нужны драйвера.
Может есть способ передать данные на HID устройство. Мне пока это не удалось.
Тут небольшой эскиз программы:
#include "DigiKeyboard.h"
#define SetBit(reg, bit) reg |= (1<<bit)
#define ClearBit(reg, bit) reg &= (~(1<<bit))
#define InvBit(reg, bit) reg ^= (1<<bit)
#define BitIsSet(reg, bit) ((reg & (1<<bit)) != 0)
#define BitIsClear(reg, bit) ((reg & (1<<bit)) == 0)
#define KEY_BACKSPACE ( 42 | 0xF000 )
#define KEY_HOME ( 74 | 0xF000 )
#define KEY_END ( 77 | 0xF000 )
//P0 PB0 Pin5 (MOSI/DI/SDA/AIN0/OC0A/OC1A/AREF/PCINT0) PB0
//P1 PB1 Pin6 (MISO/DO/AIN1/OC0B/OC1A/PCINT1) PB1
//P2 PB2 Pin7 (SCK/USCK/SCL/ADC1/T0/INT0/PCINT2) PB2
//P3 PB3 Pin2 USB_D- (PCINT3/XTAL1/CLKI/OC1B/ADC3) PB3
//P4 PB4 Pin3 USB_D+ (PCINT4/XTAL2/CLKO/OC1B/ADC2) PB4
//P5 PB5 Pin1 (PCINT5/RESET/ADC0/dW) PB5
char* myStrings[] = { "https://datacenter.com.ua/RDWeb"
, "DC\\DC1SQL"
, "https://000.000.252.000"
, "Host 2"
, "Host 3"
, "Host 4"
};
char* myLogin[] = { "datacenter\\admin"
, "sa"
, "user"
, "Login 2"
, "Login 3"
, "Login 4"
};
char* myPass[] = { "sdkgfskjsdfgsdf"
, "sdfsdfsd"
, "sdfdfsdfsdf"
, "Pass 2"
, "Pass 3"
, "Pass 4"
};
int PIN = 1234 ;
bool passOK = false;
long ptime = 0;
int PassCount = -1;
int PassLogin = 0;
void setup() {
PORTB = (1 << PB0) | (1 << PB2); //Подтяжка пина до +5в
DDRB = (0 << DDB0) | (0 << DDB2); //
DigiKeyboard.delay(2000);
inputpin ();
}
void loop() {
DigiKeyboard.sendKeyStroke(0);
while ( BitIsClear(PINB, PINB0) || BitIsClear(PINB, PINB2) ) {
;
}; //поки одна з двох кнопок натиснута
delay(300);
while ( BitIsSet(PINB, PINB0) && BitIsSet(PINB, PINB2) ) {
;
}; // поки обидві кнопки відпущені
if (BitIsClear(PINB, PINB0)) {
PassCount++;
if (PassCount == 6) {
PassCount = 0 ;
};
DigiKeyboard.print(myStrings[PassCount]);
DigiKeyboard.sendKeyStroke(KEY_HOME, MOD_SHIFT_LEFT);
PassLogin = 0;
}
if (BitIsClear(PINB, PINB2)) {
if (PassLogin == 0 ) {
DigiKeyboard.print(myLogin[PassCount]);
PassLogin = 1 ;
}
else {
DigiKeyboard.print(myPass[PassCount]);
PassLogin = 0 ;
}
DigiKeyboard.sendKeyStroke(KEY_END);
DigiKeyboard.sendKeyStroke(KEY_HOME, MOD_SHIFT_LEFT);
}
}
void inputpin () {
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.print("OK");
/* тут будет пин код при подключении
int i=0;
int n=0;
int iPIN;
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.print("Enter PIN: 0***");
DigiKeyboard.sendKeyStroke(KEY_HOME,MOD_SHIFT_LEFT);
SetBit(PINB, PINB1);
while( i<4) {
while( BitIsClear(PINB, PINB0)||BitIsClear(PINB, PINB2) ){;}; //поки одна з двох кнопок натиснута
delay(300);
while( BitIsSet(PINB, PINB0)&&BitIsSet(PINB, PINB2) ){;}; // поки обидві кнопки відпущені
if (BitIsClear(PINB, PINB0)) {n++; if (n==10) {n=0;} ; };
if (BitIsClear(PINB, PINB2)) { if (i==3) {i++ ;}
else {iPIN = iPIN*10+n; i++ ; n = 0;}; };
DigiKeyboard.print("Enter PIN: ");
DigiKeyboard.print(iPIN*10+n); //тут не відображається число типу 0000
if ((i==0)&&((iPIN*10+n)<10)) {DigiKeyboard.print("***");};
if ((i==1)&&((iPIN*10+n)<100)) {DigiKeyboard.print("**");};
if ((i==2)&&((iPIN*10+n)<1000)) {DigiKeyboard.print("*");};
DigiKeyboard.sendKeyStroke(KEY_HOME,MOD_SHIFT_LEFT)
;}
DigiKeyboard.print("Enter PIN: OK");
DigiKeyboard.sendKeyStroke(KEY_HOME,MOD_SHIFT_LEFT)*/
;
}
Кусок первого поста исказило при сохранении.
char* myStrings[] = { "Host 1" , "Host 2" , "Host 3" , "Host 4" , "Host 5" , "Host 6" };по-моему, есть еепром.
512 байт.
знаю один способ передачи данных с компьютера на клавиатуру- состояние лампочки num lock.
Где это можно посмотреть?
Заинтересовал ваш проект. А именно передача данных на сам Digispark в режиме HID клавиатуры. Получилось что-нибудь ?
Смогли общаться с устройством HID ?
Waik, у дижиспарка есть два возможных интерфейса ввода данных на ходу - терминалка DigiUSB, которую наш коллега Клапуций вроде как довёл до ума. И драйвер TrinketFakeUsbSerial создающий вирутальный ком-порт . Соответссно первый можно найти на нашем форуме, второй на сайте адафрута.
dimax, спасибо за ответ. DigiUSB использую сейчас для общения, но манипуляции и танцы с бубном с драйверами не очень нравятся. А вот про TrinketFakeUsbSerial не слышал.
Устройство используется на множестве компьютеров абсолютно различной сборки и на каждый ставить драйвер а потом запуспать управляющую софтину как-то не очень удобно, тем более что драйвер привередливый и не на все Windows ставится.
Waik, что б не связываться с дровами нужно перехватывать данные с клавиатуры, значит девайс должен быть в виде переходника в который вставляется штатная клава. Пока девайс не активирован он слушает всё, что передаёт клава, когда "увидит" ожидаемую последовательность кодов то отключает временно клаву и посылает то, что нужно. В общем и аппаратно и программно это уже серьёзная штука будет.
dimax, это уже какой-то кейлоггер получается:) мне такое не нужно. мне софтово слать команды на устройство максимально простым для конечного пользователя способом и все.
Waik, ну остаётся только читать состояния светодиодов на клаве, как хотел Okmor. Для дижиспарка в той же библе trinketHid есть возможность читать состояния светодиодов на клаве.