Password-Manager



auf dem PicoBoy Color

Die Inspiration zu diesem Projekt habe ich aus einem Artikel in der 'Raspberry Pi Geek 05/2023', veröffentlicht von Bernhard Bablok. Er beschreibt dort eine portable Anmeldehilfe für Konten und Webseiten. Mit Hilfe eines Pi Pico werden per HID die Anmeldenamen und Passwörter z.B. in den Browser eingegeben. Man braucht sich diese dann nicht mehr alle auswendig merken oder aufwendige Keypass-Tools verwenden. Für das Projekt hat er einen Pi Pico mit 0.96 Zoll LCD Display von Waveshare und als Firmware CircuitPython verwendet. Der entscheidente Punkt im Projekt ist, wie er selbst schreibt, die 'sichere Unterbringung' der Secrets, also Nutzernamen und Passwörter. Die sind nämlich in einer frei einsehbaren Pythondatei abgelegt. Damit ist das entscheidente Sicherheitsmanko klar aufgezeigt.

Aus diesem Grunde habe ich mich für einen anderen Weg entschieden, der natürlich auch keine absolute Sicherheit bietet. Aber wer hier an die Passwörter heran will, muss schon wesentlich tiefer in die Materie einsteigen. Ich beschreibe hier die Einrichtung des PasswordManagers am Beispiel eines PicoBoy Color. Auf Grund der gleichen technischen Voraussetzungen, habe ich den entsprechenden Arduino-Sketch aber auch für einen Pi Pico mit 1.14 Zoll LCD und den Pico-Geek kompiliert. Ein Unterschied besteht nur in den verschieden großen Displays und Eingabemöglichkeiten. Es waren also nur die Displayansteuerung, die Pins und Ausgabepositionen anzupassen. Mit der entsprechenden fertigen UF2-Datei ist die Einrichtung dann Schritt für Schritt identisch.

Auf den Mikrocontroller wird ein Sketch mit Hilfe der Arduino-IDE hochgeladen. Die 'Secrets' werden bei der Erstnutzung entweder vom Programmierer oder jedem anderen Nutzer des Tools via 'Serial' eingegeben und ein sechsstelliger Anmeldepin gesetzt. Das Vorgehen werde ich in dieser Anleitung weiter unten noch genau beschreiben. Wenn ich nachfolgend den Begriff EEPROM verwende, ist mir bewußt, dass beim RP2040 MC kein echter EEPROM vorhanden ist, sondern ein Bereich des Flashspeichers emuliert wird. Angesichts der wenigen Speichervorgänge ist das aber vertretbar (nur damit die 'Experten' ruhig bleiben).

Wer sich für den Quellcode des Projektes interessiert, kann sich selbigen auf meinem Github-Repository ansehen. Hinweise zur Einrichtung und zur Bedienung erfolgen hier.



Bildbox 1

Grundsätzlich besteht bei der Umsetzung folgendes Ziel:

Ein PicoBoy Color fungiert als:

* PIN-geschützter Passwort-Tresor
* Anzeige über ST7789 TFT
* Ausgabe von User/Passwort per USB-HID-Keyboard
* Secrets werden einmalig über Serial Monitor eingegeben
* Daten werden dauerhaft im EEPROM gespeichert

Die Initialisierung (Clean Start) funktioniert so:

1. EEPROM vollständig löschen (d.h. flash_nuke.uf2 ausführen)
2. PicoBoy Color mit gedrückter BOOTSEL-Taste anschließen
3. Sketch in der Arduino-IDE hochladen
4. in der Arduino-IDE das Board als 'Raspberry Pi Pico' mit COM-Port auswählen

Erster Start (leeres EEPROM):

* Gerät erkennt: keine 'Secrets'



Bildbox 2

* Eingabe der Secrets über Serial-Monitor (Beschreibung erfolgt gesondert)
* Gerät erkennt: kein PIN vorhanden
* Modus: SET_PIN


Bildbox 3

* 6-stellige PIN setzen
* PIN wird in EEPROM gespeichert

Danach wechselt das Gerät in den Anzeigemodus von Nutzername und Passwort wie in der oberen Bildbox 1. Die bis zu dieser Stelle gezeigte Funktionalität ist vollständig im 'Auslieferungszustand' enthalten. Was heißt das?

Wenn Sie sich die von mir angebotene entsprechende uf2-Datei herunterladen und wie üblich aufspielen, dann haben Sie bis auf die Notwendigkeit der Eingabe von Secrets schon alles, um das Gerät als PasswordManager nutzen zu können. Und bitte nicht wundern. Die Datei hat wirklich nur 176 KB. Vor dem Aufspielen das Ausführen der 'Flash_nuke.uf2' nicht vergessen, damit der Speicher komplett gelöscht ist.

'Download uf2-Datei für PBC'

'Download für RP Pico mit 1.14LCD'


Jetzt folgt die Übertragung der Secrets:

0. Vorweg ein Wort zu den zulässigen Zeichen für Nutzernamen und Passwörter:
Da in der Datei 'secrets.txt' das ';' als Trennzeichen verwendet wird, ist es bei Nutzername und Passwort ausgeschlossen. Ansonsten können alle Klein- und Großbuchstaben des deutschen Alphabets (ausser Umlaute ä, ö, ü und ß) benutzt werden. Es gibt auch Sonderzeichen der deutschen QWERTZ-Tastatur.
Über die Shift-Taste sind möglich: ' ! ', ' $ ', ' % ', ' & ', ' / ', ' ( ', ' ) ', ' = ', ' ? ', ' * ', ' : ',
Über die AltGr-Taste sind möglich: '@', '{', '[', ']', '}'
Damit stehen z.Z. 26 Kleinbuchstaben, 26 Großbuchstaben, 10 Ziffern und 16 Sonderzeichen zur Verfügung, d.h. es lassen sich über 4.7 Trilliarden (eine 4 mit 21 Nullen) Kombinationen für das Passwort bilden. Wer beim Angebotsnamen die deutschen Umlaute vermisst, kann ohne Einschränkung 'ae', 'oe' oder 'ue' schreiben. Beim Nutzernamen wird häufig eine E-Mailadresse gebraucht. Dafür steht das '@' zur Verfügung und 4,7 Trilliarden Passwort-Kombinationen sollten auch ausreichen.

1. Ich habe es extra so gemacht, dass der erfahrene Nutzer die Secrets per Hand im 'seriellen Monitor' der Arduino-IDE der Reihe nach eingeben kann und als Abschluss einmal zusätzlich auf 'Enter' drückt (eine Leerzeile) oder

2. alle anderen Nutzer die Übertragung aus einer vorbereiteten Textdatei mit einem kurzen Python Script im Thonny durchführen können.

Das Format der einzelnen Zeilen bzw. der Textdatei muss so aussehen:

Amazon;mail@example.com;SuperSecret123
Github;gituser;Token456
WLAN;HomeSSID;WifiPass

*****


Wichtig ist, dass immer drei Strings (Angebotsname, Nutzername, Passwort) getrennt durch Semikolon angegeben werden. Der Name der Textdatei muss lauten:

secrets.txt

Nach dem letzten Secret muss eine Leerzeile folgen. Was danach steht ist nicht mehr relevant. Das Programm interpretiert die Leerzeile als 'Ende' der Eingabe. Zur Zeit sind 10 Secrets möglich aber nicht zwingend erforderlich.

Um die Secrets nun im Thonny zu übertragen, schließen Sie Ihr Gerät am PC an und öffnen die Thonny-IDE. Gehen Sie zu 'Extras' -- 'Optionen' -- 'Interpreter' . Um zunächst den COM-Port herauszufinden, stellen Sie 'MicroPython (Raspberry Pi Pico) ein und klicken in der Mitte auf 'Port'. Dort steht dann z.B. Serielles USB-Gerät (COM11). Damit wissen Sie, über welchen COM-Port der Pico mit dem PC verbunden ist.

Im nächsten Schritt gehen Sie oben wieder auf 'Art des Interpreters...' und wählen Lokales Python 3. Das sollte, wenn Sie Thonny sonst auch nutzen, kein Problem sein. Dann noch 'OK' klicken und die Übertragung mit dem PythonScript kann beginnen. Beim Einsetzen des Code in die Thonny-IDE achten Sie darauf, dass in Zeile 6 Ihr COM-Port steht. Bevor Sie die Python-Datei ausführen, speichern Sie diese z.B. unter dem Namen serial_senden.py in den selben Ordner, wie die Secrets-Datei secrets.txt.

  
  
1  import serial
2  import time
3  import os
4
5  # ===================== Konfiguration =====================
6  SERIAL_PORT = "COM11"      # COM-Port des Pico anpassen
7  BAUDRATE = 115200
8  FILENAME = "secrets.txt"
9  LINE_DELAY = 0.1           # Pause zwischen Zeilen (Sekunden)
10
11 # ===================== Datei prüfen =====================
12 if not os.path.isfile(FILENAME):
13     print(f"Fehler: Datei '{FILENAME}' existiert nicht!")
14     exit()
15
16 # ===================== Serial-Verbindung =====================
17 try:
18     ser = serial.Serial(SERIAL_PORT, BAUDRATE, timeout=1)
19     print(f"Pico verbunden auf {SERIAL_PORT}. Warte kurz auf Start...")
20     time.sleep(2)  # Pico Bootzeit
21 except Exception as e:
22     print(f"Fehler beim Öffnen von {SERIAL_PORT}: {e}")
23     exit()
24
25 # ===================== Datei senden =====================
26 sent_count = 0
27 with open(FILENAME, "r", encoding="utf-8") as f:
28     for line_num, line in enumerate(f, start=1):
29         line = line.strip()
30
31         # Kommentare und leere Zeilen ignorieren
32         if not line or line.startswith("#"):
33             continue
34
35         # Prüfen: genau 2 Semikolons
36         if line.count(";") != 2:
37             print(f"Zeile {line_num} übersprungen (falsches Format): '{line}'")
38             continue
39
40         # Zeile senden
41         try:
42             ser.write((line + "\n").encode("utf-8"))
43             sent_count += 1
44             print(f"Gesendet [{sent_count}]: {line}")
45             time.sleep(LINE_DELAY)
46         except Exception as e:
47             print(f"Fehler beim Senden der Zeile {line_num}: {e}")
48
49 # ===================== Ende der Eingabe =====================
50 ser.write(b"\n")  # Leerzeile signalisiert Pico: alles gelesen
51 print("\nImport abgeschlossen! Gesamtanzahl gesendeter Secrets:", sent_count)
52
53 ser.close()

Starten Sie das Script. In der Kommandozeile von Thonny können Sie die Übertragung verfolgen. Nach erfolgreichem Abschluss erwartet der PicoBoy Color die Eingabe eines sechsstelligen Pins, mit dem Sie ab jetzt das Programm starten.


Bildbox 3

Bedienung:
Damit ist die Einrichtung abgeschlossen. Beim Betätigen der Tasten wird davon ausgegangenm, dass Sie das Gerät so halten, wie in den Bildern zu sehen (Joystick oben, A-Taste mitte, B-Taste unten). Sie geben also bei jedem Start Ihren persönlichen Pin ein. Jede Stelle wird mit 'OK' (Joystick CENTER) abgeschlossen. Danach wählen Sie mit 'up' und 'down' den gewünschten Eintrag im Menü aus. Der steht immer farbig markiert in der oberen Zeile. Gehen Sie nun z.B. auf die entsprechende Webseite und setzen den Cursor auf das Eingabefeld des Nutzernamen. Im Display steht dieser in der mittleren Zeile. Durch Drücken der A-Taste senden Sie per HID den Eintrag. In der unteren Zeile des Displays steht das Passwort (nur als Sternchen sichtbar). Setzen Sie den Cursor in das Passwortfeld des Browsers und drücken die B-Taste. Dadurch wird das Passwort per HID gesendet und im Browser eingetragen. Beim Betätigen der 'Enter' Taste auf der Tastatur erfolgt der Login.

Meine Erfahrung zeigt, dass der PC den PicoBoy Color mitunter nicht richtig als USB-Gerät erkennt. Abhilfe schaffen Sie durch Abziehen bzw. Ausschalten des PicoBoy Color und erneutes Wiederherstellen der USB Verbindung.



Viel Spass und Erfolg mit dieser Anwendung.