Digispark как хранитель паролей и передача данных на HID устройство.

Okmor
Okmor аватар
Offline
Зарегистрирован: 16.10.2015

Вот решил запилить аппаратный хранитель паролей. Для базы девайса использую 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)*/
  ;
}

 

Okmor
Okmor аватар
Offline
Зарегистрирован: 16.10.2015

Кусок первого поста исказило при сохранении.

char* myStrings[] = {   "Host 1"
                      , "Host 2"
                      , "Host 3"
                      , "Host 4"
                      , "Host 5"
                      , "Host 6"
                    };

 

toc
Offline
Зарегистрирован: 09.02.2013

по-моему, есть еепром.
512 байт.

toc
Offline
Зарегистрирован: 09.02.2013

знаю один способ передачи данных с компьютера на клавиатуру- состояние лампочки num lock.

Okmor
Okmor аватар
Offline
Зарегистрирован: 16.10.2015

toc пишет:
знаю один способ передачи данных с компьютера на клавиатуру- состояние лампочки num lock.

Где это можно посмотреть?

Waik
Offline
Зарегистрирован: 28.05.2014

Заинтересовал ваш проект. А именно передача данных на сам Digispark в режиме HID клавиатуры.  Получилось что-нибудь ?

Waik
Offline
Зарегистрирован: 28.05.2014

Смогли общаться с устройством HID ?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Waik, у дижиспарка есть два возможных интерфейса ввода данных на ходу - терминалка DigiUSB, которую наш коллега Клапуций вроде как довёл до ума. И драйвер TrinketFakeUsbSerial создающий вирутальный ком-порт . Соответссно первый можно найти на нашем форуме, второй на сайте адафрута.

Waik
Offline
Зарегистрирован: 28.05.2014

dimax, спасибо за ответ. DigiUSB использую сейчас для общения, но манипуляции и танцы с бубном с драйверами не очень нравятся. А вот про TrinketFakeUsbSerial не слышал. 

Устройство используется на множестве компьютеров абсолютно различной сборки и на каждый ставить драйвер а потом запуспать управляющую софтину как-то не очень удобно, тем более что драйвер привередливый и не на все Windows ставится. 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

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

Waik
Offline
Зарегистрирован: 28.05.2014

dimax, это уже какой-то кейлоггер получается:) мне такое не нужно. мне софтово слать команды на устройство максимально простым для конечного пользователя способом и все. 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Waik, ну остаётся только читать состояния светодиодов на клаве, как хотел Okmor. Для дижиспарка в той же библе trinketHid есть возможность читать состояния светодиодов на клаве.