Avtor: dr. Simon Vavpotič
2018_264_42
So hekerji že uganili vaše računalniško geslo? Se učite zapletena računalniška gesla na pamet? Jih pogosto pozabite? Rešitev je strojni upravljalnik gesel na osnovi PIC32.
Strojni upravljalnik gesel omogoča pomnjenje prijavnih gesel, varen vnos novih gesel preko PC, generiranje naključnih kompleksnih gesel, varno hrambo podatkov (funkcionalnost podatkovnega ključka), posnema tipkovnico in lahko samodejno vnese geslo v računalnik. Pomembna je tudi PIN koda, s katero ga odklenemo ob začetku uporabe in preprečuje njegovo zlorabo.
Gradnje upravljalnika gesel se bomo lotili v dveh korakih. Tokrat bomo izdelali električno vezje in osnovno programsko aplikacijo, ki bo omogočala ročno ustvarjanje in varno hrambo seznama gesel ter samodejno tipkanje gesel v osebni računalnik. V drugem delu bomo dodali še PIN kodo, kriptografijo in ustvarjanje močnih naključnih gesel. Pri razvoju programske opreme si bomo izdatno pomagali s programsko knjižnico Microchip Harmony 2.05 in razvojnim okoljem MPLAB X 4.05.
Ta vsebina je samo za naročnike
Načrt
Strojni upravljalnik gesel je zasnovan okoli zmogljivega mikrokontrolerja z grafičnim prikazovalnikom in enostavno tipkovnico, ki poganja programsko aplikacijo za upravljanje gesel. Aplikacija je s tem ločena od računalnikov, kjer gesla uporabljamo. Zato ni nevarnosti, da bi kak računalniški virus, trojanski konj ali črv odkril in prekopiral zbirko gesel.
Strojni upravljalnik gesel posnema delovanje tipkovnice, da nam gesel ni potrebno pretipkovati v računalnik, ali celo izpisovati na zaslon. Gesla mikrokontroler hrani v svojem notranjem pomnilniku, ki se uporabniku osebnega računalnika predstavi kot pogon za masovno hrambo podatkov. Datoteko z gesli urejamo kar v urejevalniku besedil na varnem PC.
Poleg urejanja gesel ima urejevalnik gesel tudi možnost nastavitev delovanja. Nastavimo lahko vidnost pogona za masovno hrambo podatkov, kakor tudi jezik posnemanja tipkovnice. Pogon za masovno hrambo podatkov želimo skriti zaradi varnosti datoteke z gesli, saj je tako nobena aplikacija na PC ne more prekopirati. Strojni upravljalnik gesel lahko tako uporabljamo tudi na potencialno ogroženem PC.
Pri delu z aplikacijo uporabljamo tipkovnico strojnega upravljalnika gesel s tremi tipkami: gor, dol in potrdi. Na ta način lahko izberemo in izpišemo želeno geslo, ne da bi za to morali uporabiti tipkovnico PC. To preprečuje aplikacijam na PC, da bi na kakršenkoli način izpisale katero od shranjenih gesel. Poleg tega, se s tipkami pomikamo tudi preko menijev z nastavitvami, kjer lahko nastavimo vidnost pogona za masovno hrambo podatkov, kakor tudi izberemo jezik za posnemanje delovanja tipkovnice.
Slednji je pomemben pri vnosu posebnih znakov, ki so na različnih tipkovnicah dosegljivi preko različnih tipk in njihovih kombinacij. Vsekakor lahko jezik nastavimo tudi v Windows ali drugem operacijskem sistemu. Vendar je enostavneje, če lahko jezik izberemo že v strojnem urejevalniku gesel in nam ga nato ni potrebno spreminjati na PC.
Električna shema
Za osnovo smo uporabili 32-bitni PIC32MX250F128B s 128 kB EEPROM in 32 kB RAM (za bolj zahtevne smo podprli tudi PIC32MX270F256B s 256 kB EEPROM in 64 kB RAM), ki smo mu dodali 1,3 colski prikazovalnik OLED za Arduino (izdelovalca LANMU) z ločljivostjo 128 x 64 pik ter kristala z 8 MHz in 32,768 kHz. Prvi omogoča komunikacijo preko povezave USB, drugi pa poganja uro realnega časa. V tem nadaljevanju sicer ure realnega časa ne bomo uporabili, je pa pomembna pri ustvarjanju naključnih gesel, saj lahko na osnovi meritve realnega časa določimo seme za naključni generator.
Prikazovalnik OLED je s PIC32MX250F128B povezan s petimi signali: CLK, MOSI, RESET, DC in CS. Komunikacija poteka po protokolu SPI. Signali preko vmesniške ploščice potujejo v krmilnik SH1106 (ali SH1306, odvisno od verzije prikazovalnika), ki poleg 4-žičnega SPI omogoča še 4 načine komunikacije, a nas vmesniška plošča za Arduino omeji na le dva: SPI in I2C. Originalna nastavitev naše ploščice je bila komunikacija preko I2C. Zato je potrebno premakniti 4,7 k ohmski upor na položaj SPI (oziroma se držati navodil proizvajalca vmesniške kartice).
Žal je miniaturni upor (ali upori) prispajkan v tehniki SMD, tako da opravilo ni niti malo prijetno za tiste, ki tega niste vajeni. Lahko si pomagamo s segrevanjem kontaktov z dvema spajkalnikoma, ali pa uporabimo rokohitrske spretnosti in delo opravimo z enim. K sreči vsaj na mestu R8 (pri vmesniški ploščici LANMU) ni kratkostične povezave (ki bi jo potrebovali za delo preko I2C). Tako, da se nam ni potrebno ukvarjati še s tem.
Vsekakor je potrebno poudariti, da je različnih vmesniških plošč s prikazovalnikom OLED s krmilnikoma SH1106 in SH1306 zelo veliko. Pri vsaki nekoliko drugače spremenimo prednastavljen način delovanja.
Strojni upravljalnik gesel ima svojo tipkovnico s tremi mikrostikali, ki je izdelana na posebnem tiskanem vezju, kar omogoča lažjo vgradno v ohišje. Sicer je vsako stikalo vezano neposredno med napajanje in vhod mikrokontrolerja. Uporov za vleko napetostnega nivoja navzdol ne potrebujemo, saj nam to omogoča že ustrezna nastavitev vhodov PIC32MX250F128B .
Zadnji del povezovalne sheme je 3,3 V napetostni regulator, s katerim napajamo le mikrokontroler. OLED napajamo neposredno s 5 V, saj ima njegova vmesniška ploščica že vgrajen lastni 3,3 V regulator. SH1106 torej deluje na 3,3 V (je pa toleranten tudi na napetostne nivoje do 5 V, glej članek Novi OLED prikazovalnik v SE227) zato lahko izhode PIC32MX250F128B neposredno povežemo.
Vsekakor velja dodati, da je večina tovrstnih vmesniških vezij s prikazovalniki OLED izdelana za 3,3 V, kar omogočajo tudi nekateri Arduini. Pri teh je potrebno na napajalni priključek (Vcc) povezati napetost iz 3,3 V regulatorja.
Naprava USB
Naslednji korak je priprava programske opreme. Strojni upravljalnik gesel se prijavi na osebni računalnik kot naprava USB z lastnostma tipkovnice in pogona za masovno hrambo podatkov. Med primeri v Microchipovi programski knjižnici Microchip Harmony teh lastnosti ne najdemo združenih. Zato se moramo pri pripravi skeletne programske kode nekoliko bolj potruditi.
Mi smo začeli s primeroma tipkovnice in standardnega vmesnika za interakcijo človeka z računalnikom z dodanim pogonom za masovno hrambo podatkov. Iz slednjega smo v primer tipkovnice dodali vse potrebno za dodatno lastnost pogona za masovno hrambo podatkov.
Najprej smo v nastavitvah Microchip Harmony kot dodatno lastnost dodali še pogon za masovno hrambo podatkov. Nato smo z orodjem WinMerge iz drugega primera prenesli še potrebne opisnike in nastavitve pogona za masovno hrambo podatkov velikosti 32 kB. Za zmogljivejši mikrokontroler, PIC32MX270F256B, smo pogon za masovno hrambo podatkov povečali na 128 kB. Zanimivo je, da slednji poleg programskih knjižnic Microchip Harmony in ustreznih nastavitev ne potrebuje druge uporabniške programske kode in sam vzdržuje svoje delovanje.
Masovna hramba podatkov in datotečni sistem
Povezave funkcionalnosti tipkovnice in pogona za masovno hrambo podatkov smo se lotili preko datotečnega sistema. Slednji je neposredno programsko dostopen preko 32 kB (oziroma 128 kB) velikega polja »diskImage«. Vanj se shrani vsaka sprememba v obstoječih datotekah (v začetku je to le vgrajena datoteka FILE.TXT) in vse nove datoteke. Čeprav ima pogon za masovno hrambo podatkov le nekaj deset kB, je to kljub temu dovolj za hrambo zbirke kompleksnih gesel. Bistveno je, da lahko do njega dostopa tudi programska aplikacija za upravljanje gesel, ki smo jo razvili na osnovni skeletne kode za tipkovnico USB.
Potrebujemo torej podporo za datotečni sistem. Ena izmed možnosti je uporaba v Microchip Harmony vgrajene podpore za datotečni sistem. Vendar se za to nismo odločiti, saj je potrebno vsakokrat, ko z aplikacijo znotraj mikrokontrolerja dostopamo do datotečnega sistema, odklopiti povezavo USB.
Namesto tega smo raje vgradili lastno podporo za datotečne sisteme FAT (v našem primeru smo uporabili FAT12), ki jo lahko najdemo kot zastonjsko programsko knjižnico v spletu (s spletnim brskalnikom poiščemo FAT FS – ff007a.zip, ali gremo na spletni naslov: http://elm-chan.org/fsw/ff/00index_e.html). Sestavljajo jo štiri datoteke: ff.c, ff.h, diskio.c in diskio.h. Prvi dve vsebujeta standardne visokonivojske funkcije datotečnega sistema, ki jih uporabljamo v svojih programih, drugi dve pa skeletno kodo za nizkonivojske funkcije, s katerimi dostopamo neposredno do sektorjev na podatkovnem nosilcu.
Priložene je dovolj dokumentacije, da zlahka preuredimo in dopolnimo vsebino datoteke diskio.c, ki podpira neposredno branje sektorjev pogona za masovno hrambo podatkov. Mi smo morali pripraviti predvsem funkcijo disk_read, ki iz polja diskImage prebere želeno število sektorjev. Ostalo je bilo enostavno, saj smo med izvorno kodo projekta dodatno vključili le datoteki diskio.c in ff.c ter med datoteke glav dodali diskio.h in ff.h. S tem smo dobili osnovno podporo za branje vsebine datotek iz polja diskImage.
Velja omeniti še, da smo med nastavitvami v diskio.h definirali še _READONLY 1; kar pomeni, da lahko iz datotečnega sistema samo beremo. S tem smo si bistveno poenostavili delo, saj ni bilo potrebno definirati funkcije za zapisovanje sektorjev, niti funkcije, ki vrača sistemski čas, ki se vpiše v podatke nove ali spremenjene datoteke.
Posnemanje tipkanja
Skeletna programska koda za tipkovnico USB podpira delovanje ene tipke, s pritiskom katere lahko po vrsti izpišemo vse črke abecede. Naša aplikacija zahteva precej več. Znati mora izpisati poljuben znakovni niz, tako da posnema delovanje tipkovnice. Čeprav se zdi enostavno, ni čisto tako. Tipkovnica USB ima za vsako fizično tipko določeno svojo skenirno kodo. A znaki iz nabora ASCII niso isto kakor tipke. Za nekatere znake dosežemo zgolj s kombinacijo kontrolne in navadne tipke. S kontrolno tipko (npr. Shift) izberemo raven tipkovnice, nato pa s pritiskom navadne tipke še konkretni znak na tej ravni. Denimo, črki a in A sta na isti tipki, vendar prvo dosežemo neposredno, pri drugi pa mora biti pritisnjena tudi tipka Shift. To moramo upoštevati tudi pri posnemanju tipkanja računalniškega gesla. Upoštevati moramo tudi razlike med nacionalnimi tipkovnicami, oziroma se moramo prilagoditi trenutno izbrani tipkovnici na PC. Tolmačenje skenirnih kod pritisnjenih tipk namreč poteka šele na ravni operacijskega sistema. Za vsak jezik bi tako potrebovali nekoliko drugačno prekodirno tabelo iz kod ASCII v skenirne kode tipk. Mi smo se za enkrat omejili na slovenščino in ameriško angleščino.
Sicer velja omeniti, da je standard USB za tipkovnico kar precej splošen in omogoča hkratno zaznavanje do šest pritisnjenih navadnih tipk ob katerikoli izbrani kombinaciji osmih kontrolnih tipk. Vendar pri izpisu računalniškega gesla potrebujemo le po eno hkrati pritisnjeno navadno tipko in kombinacijo kontrolnih tipk. Obenem je potrebno paziti, da vsakemu pritisku tipke sledi premor (ko ni pritisnjena nobena tipka). Operacijski sistem ima namreč vgrajeno varnostno zakasnitev pred ponavljanjem izpisa iste tipke. Na primer, če hočemo izpisati geslo z zaporednima črkama a, moramo pritisniti tipko A, jo spustiti in nato še enkrat pritisniti. Natančno to moramo storiti pri posnemanju tipkanja. Tudi ko prenehamo vpisovati geslo, moramo spustiti vse tipke, še posebej kontrolnih. Operacijski sistem namreč združuje vse kontrolne tipke vseh priključenih tipkovnic. Če upravljalnik gesel »pozabi« spustiti katero od kontrolnih tipk, bo prava tipkovnica ves čas delovala na napačni ravni. Si predstavljate tipkanje, ko je neprestano pritisnjena desna tipka Alt? Če upravljalnik gesel napačno sprogramiramo, pomaga le, da ga fizično odklopimo iz vtičnice USB in spet priklopimo.
Izris besedil in menijev na OLED
SH1106 (oz. SH1306) nima generatorja znakov, zato pa ima posebno ureditev pik, ki omogoča enostaven izpis znakov višine 8 pik (n krat 8 pik). Pike so razdeljene na 8 strani, vsako stran pa sestavlja 136 bajtov (prikaže se le 128 bajtov, ostali ostanejo skriti za robovoma prikazovalnika). To si lahko predstavljamo kot, da bi pokončno zložili stolpce po 8 pik v vrsto s 136 stolpci. Zato lahko posamezen znak izpišemo kot zaporedje m stolpcev (m je odvisen od širine znaka). Mi smo izbrali znake velikosti 5 x 8 pik, ki smo jih ločili s praznim stolpcem. Tako vsak znak skupaj s presledkom zasede 6 bajtov na zaslonu. K sreči smo v internetu našli tudi slikovno-kodno tabelo znakov, tako da nam jih ni bilo potrebno risati. V datoteki MultiLCD-master.zip, ki jo poiščemo na spletnem naslovu https://github.com/stanleyhuangyc/MultiLCD, najdemo celoten primer programja za upravljanje zaslona OLED s krmilnikom SH1106 ali SH1306.
Za izvedbi inicializacije OLED je dovolj, da vključimo zaslon in ga pobrišemo (ukaz 0xAF in pošljemo zaporedja podatkov po 136 ničel, s katerimi napolnimo vse strani zaslona). Nato izris na zaslonu postavimo na ničto stran, na prvo lokacijo, ki je vidna na zaslonu.
Programska koda generatorja znakov je preprosta. Slike znakov so dolge po 5 bajtov in so urejene skladno s tabelo znakov ASCII. Zato vsako kodo znaka pretvorimo v zaporedje kod za njegov izris. K zaporedju vsakokrat dodamo še prazen bajt, ki ločuje posamezne znake. Kot dodatno lastnost smo dodali še izris inverznih znakov tako, da se vse slike znakov in presledki invertirajo (funkcija SPI1WriteChar5x8Ex_OLED(char ch, BYTE style)). Poznamo tudi običajno in inverzno brisanje strani (oziroma vrstic znakov), ki sta za PIC32 prav tako enostavni funkciji, saj ima ta strojno podporo za protokol SPI pa tudi strojni izravnalnik. Več bajtov preko SPI prenesemo tako, da jih zaporedno vpišemo v register SPIxBUF (kjer je x številka enote SPI, mi smo uporabili prvo).
Sedaj gremo lahko od enostavnih funkcij z izris znakov k sestavljenim. Denimo, funkcija SPI1PrintEx_OLED(char *s,BYTE pg, BYTE style) izpiše znakovni niz s, ki se mora končati s kodo ASCII 0, na stran pg v obliki style, kjer je style lahko 0 (normalni izpis) ali 1 (inverzni izpis). Za izpis menijev smo zgradili funkcijo SPI1PrintMenu_OLED(char *s,int active,BYTE pg), kjer je s znakovni niz, v katerem so naslov in vrstice menijo ločeni z navpičnico (znak »|«).
Aplikacija za upravljanje gesel
Odločili smo se za hierarhični sistem menijev, kjer lahko na najvišjem nivoju izberemo eno od treh funkcionalnosti: izpis izbranega gesla, skrivanje pogona za masovno hrambo podatkov in izbiro vrste posnemane tipkovnice. Če izberemo prvo možnost, se na OLED odpre izbira gesel, ki jih aplikacija prebere iz datoteke FILE.TXT v RAM mikrokontrolerja. Na OLED se prikaže samo naziv gesla, geslo pa se izpiše na PC ob pritisku na tipko na strojnem upravljalniku gesel.
Omenimo še to, da ima datoteki FILE.TXT vsako geslo opis, ki je s tabulatorjem ločen od gesla, ki se zaključi s prehodom v novo vrstico ali s kodo 0. Tako je vsako geslo v svojih vrstici datoteke. Aplikacija prebere gesla v RAM in tam so na voljo uporabniku.
Skrivanje pogona za masovno hrambo podatkov je pomembno zato, da preprečimo neavtoriziran dostop do datoteke FILE.TXT. Tako je ob normalnem delovanju strojnega upravljalnika gesel dostop do varovanih podatkov vedno zaklenjen.
Zadnja opcija omogoča izbiro posnemane tipkovnice. S tem lahko delovanje strojnega upravljalnika gesel prilagodimo izbrani tipkovnici v operacijskem sistemu računalnika. S tem zagotovimo pravilen izpis gesel, tako kot so zapisana v datoteki FILE.TXT.
Kako začeti?
Za začetek potrebujemo mikrokontroler in nekaj osnovnih elektronskih komponent. Microchipove mikrokontrolerje ni težko naročiti preko spleta (npr. na http://www.microchipdirect.com ali http://www.farnell.com). Datoteki HEX z vgrajeno programsko kodo za mikrokontrolerje PIC32MX250F128B in PIC32MX270F256B najdemo na spletni strani https://sites.google.com/site/pcusbprojects. Poleg je tudi nekaj izvorne kode, s katero si lahko pomagamo, če želimo izdelati lasten projekt.
Prihodnjič
Ukvarjali se bomo z algoritmi za kodiranje podatkov in samodejno generiranje močnih naključnih gesel. V aplikacijo na PIC32 bomo dodali tudi vnos varnostne kode pin ob priklopu upravljalnika gesel na osebni računalnik. Nekoliko bomo razširili tudi aplikacije v PIC32, da bo podpirala dodatne opcije.