Il Digital Green Certificate (spesso chiamato green pass) è un certificato digitale, comune a tutta l’Unione Europea, che attesta:
- l’avvenuta vaccinazione
- l’esito negativo di un test
- la guarigione dal virus
Viene normalmente rilasciato come qrcode, per rendere più veloce la sua lettura da parte delle app di verifica.
A livello tecnico, le informazioni anagrafiche dell’utente e dell’evento che viene certificato sono per prima cosa codificate in formato JSON, seguendo una guideline europea. I dati in formato JSON vengono quindi ulteriormente elaborati, fino ad arrivare ad una stringa in base45 che viene rappresentata come qrcode:
Uno dei passaggi più importanti è la firma digitale (protocollo COSE) che garantisce il fatto che il DGC sia stato emesso da un ente autorizzato e che i dati in esso contenuti non siano stati alterati.
Vista l’importanza che la validazione di un DGC sta assumendo in Italia, ho pensato di realizzare un progetto, basato su Raspberry Pi, che:
- legge il qrcode attraverso una pi camera
- effettua tutte le verifiche
- accende un LED verde/rosso in base all’esito
Il progetto – chiamato Raspberry DGC – è disponibile nel mio repository Github e si compone di due applicazioni.
La prima applicazione, sviluppata per NodeJS e chiamata validatorServer, riceve tramite chiamata HTTP la stringa base45 di un DGC e restituisce l’esito tramite status code (200 = OK, 400 = KO).
La seconda applicazione, sviluppata in linguaggio Python, gestice la pi camera, ricerca qrcode, chiama il server per la validazione e accende il LED corrispondente all’esito. Questa applicazione ha il nome di cameraClient.
Infine, sempre nel repository Github, sono disponibili i files per realizzare con una stampante 3d l’enclosure:
Nel seguente filmato trovate una spiegazione dettagliata del funzionamento del progetto e potete vedere la validazione di qualche DGC… buona visione!
ciao volevo sapere se era possibile modificare lo script python sul lato client (cameraclient.py) per poter utilizzare lo stesso progetto però con un lettore di qr usb ? se si mi potresti spiegare come? grazie
ciao Sergio, direi che più che modificare il codice python, va proprio rifatto perché le due funzionalità principali (gestione videocamera e scansione qrcode) di cameraClient sono direttamente fatti “in hardware” dal lettore. Dovresti quindi scrivere un programma che riceve dal lettore i dati del qrcode (nella modalità prevista dal lettore, vedo che alcuni sono via UART, altri emulano una tastiera…) e inviarli al validatorServer. Non avendo a disposizione il lettore che pensi di usare non riesco ad essere più preciso…
se ti puo’ esser di aiuto io ho usato un lettore qr USB e uso questo script:
https://gist.github.com/lucadentella/64c3996ceb1519797a22c0637024f9f1
(NDLuca: ho messo su Gist il codice per renderlo più leggibile, grazie Carlo!)
figurati e perdonami per il layout … non son un programmatore … mi ci diletto per passione, piuttosto mi chiedevo se ci fosse una maniera sempre tramite python oppure da app.js di attestare l’aggiornamento dei certificati e lo scambio dati per la validazione …
Ciao, Per caso hai idea come discriminare il Green pass dal super Green pass?
ciao, semplicemente se vuoi fare la verifica “rafforzata”, non accettare come valido un GP che abbia il dato “T” (= test). La differenza è tutta nel modo in cui lo verifichi, non nel GP in se.
ciao luca ho capito perfettamente quello che dici , il lettore in questione è un lettore che emula di fatto una tastiera , infatti se scansiono qualcosa con un file di testo aperto lui mi scrive sul file . Comunque per iniziare a capire qualcosa sto provando innanzi tutto a cambiare lo script per utilizzare una webcam usb . Almeno in questo sarebbe più semplice no ?
ciao Sergio, penso di si: dovrebbe essere sufficiente sfruttare le funzionalità della libreria OpenCV, già inclusa nel programma. Un altro utente su Github mi chiedeva informazioni proprio per lavorare a tale modifica…
ciao luca , si infatti ora sono riuscito a far funzionare la webcam usb e funziona , anche perche con la picamera ho problemi di messa a fuoco , quando i qr sono un po sgranati , mentre con la cam usb no .
Comunque pensandoci , con il lettore qr code che ho , visto che comunque è riconosicuto come un dispositivo hid , dovrei in realtà implementare , al posto dello stream video , un input da tastiera , giusto ? cioe lanciare il validator , lanciare il python , e in quel momento lui ti da a terminale : inserisci la stringa del qr code , gia tradotta in base45 . Quindi sara quella la richiesta da inviare tramite http al server , e lui risponde 400 o 200 . Almeno in teoria
ancora ciao e grazie per il supporto . oggi sono riuscito , tramite la funzione input a far “leggere” direttamente da qr code scanner , e inviare la richiesta a validatorserver , solo che ho notato che la lettura del green pass dal lettore qr la scrive in maniera differente da quello che dovrebbe essere il fornato che deve accettare il server con il risultato che tutti i green pass non superano la validazione . io sono sicuro che ha a che fare con l’encoding della stringa che genera il lettore , dovrebbe essere l’ultimo passaggio e poi l’ho fatto , ti chiedo per cortesia di aiutarmi . questo e lo script attuale che mi da questo problema
import argparse
import datetime
import time
import requests
barcodescan = input(“Scrivi qualcosa e premi INVIO: “)
print(barcodescan)
found = set()
while True:
barcodeData = barcodescan
if barcodeData not in found:
payload = {‘dgc’: barcodescan[0]}
r = requests.get(‘http://localhost:3000/’, params=payload)
print(‘Return code: ‘, r.status_code, ‘, Text: ‘, r.text)
if r.status_code == 200: print(“Green Pass Valido”)
else: print(“Green Pass NON Valido”)
e come io ho notato il lettore genera un codice che inizia per HC1ç6BFOXN% , come puoi vedere gia il 4 carattere è diverso …
ma la stringa letta dal lettore è uguale a quella che leggi ad esempio scansionando il qrcode con un app? Non dovrebbe contenere caratteri estesi, tipo quello che indichi tu: “ç”
setta la tastiera UK, il lettore QR ti restituisce un input come se fosse digitato da tastiera … io ho risolto cosi’ su un b3+
Buongiorno Sergio,
precisando che non sono un programmatore, ho provato ad installare il tuo software.
sono partito da una installazione pulita di raspbian su un pi Zero ed eseguito i passaggi dell´installazione come da github.
giá dal punto “4. Install NodeJS libraries” inizinao i miei problemi: devo effettuare un “cd raspberry-dgc” per trovarmi nella cartella giusta. “npm install” risponde con programma non trovato. Ho provato a installare un paio di versioni di node.js con vari tutorial presi dal web ma continuo ad avere errori. anche cercando di avviare “python3 cameraClient.py” ricevo vari errori ma non ho indagato oltre non riuscendo a fare funzionare node. Mi puoi dire dove sto sbagliando?
Grazie e buona giornata
ciao Andrea, penso tu stia chiedendo a me (o stai usando il codice di Sergio?). Stai usando la raspbian lite? Perché la versione “completa” ha già sia node che python installati, per questo non li ho contemplati nel documento di how-to. I passaggi sono comunque davvero semplici, segui questa guida e fammi sapere se così risolvi.
eh lo so che in teoria dovrebbe scansionare gia il codice in formato giusto , ma non riesco proprio a capire percheè mi mette il carattere ç al posto dei : … è l’unico carattere diverso , sto davvero impazzendo perchè poi la richiesta al server me la invia , ovviamente restituisce errore :S
Il lettore di qr code è un sunmi scanning box ns010 , e ripeto se lo collego a un mac me lo rileva come una tastiera , se apro un editor di testo mi scrive i codici che scansiono , provando con dei codici semplici non mi da variazioni tra cio che legge e cio che stampa , mentre per i green pass mi da l’errore
se puoi e vuoi ti posso lasciare il mio contatto così magari possiamo trovare assieme una soluzione , sta cominciando a fumarmi la testa 😀
Ciao,
prova a cambiare l’impostazione del lettore del barcode impostando la lingua inglese.
Se è un datalogic trovi i codici di impostazione sul manuale del lettore.
Buongiorno Luca, scusami per la confusione con i nomi. O fatto una nuova installazione, ma credo che la versione di node installata non sia compatibile.
Raspberry Pi OS with desktop and recommended software
Release date: May 7th 2021
Kernel version: 5.10
pi@raspberrypi:~/raspberry-dgc/validatorServer $ npm install
npm WARN npm npm does not support Node.js v10.24.0
Il tutorial che mi hai indicato non é compatibile con arm.
o provato questo: https://linuxize.com/post/how-to-install-node-js-on-raspberry-pi/
per installare la verione 9.8.4: installandola da utente pi mi da ” permission denied, access ‘/home/pi/raspberry-dgc/validatorServer'”
Ho ppoi provato poi a installare tutto da sudo,
ma si pianta anche li con una marea di errori.
lanciando invece lo script python ottengo questo:
python3 cameraClient.py
RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd
Traceback (most recent call last):
File “cameraClient.py”, line 6, in
import cv2
File “/home/pi/.local/lib/python3.7/site-packages/cv2/__init__.py”, line 5, in
from .cv2 import *
ImportError: numpy.core.multiarray failed to import
Mi potresti gentilmente dire quale versione di node.js e i pacchetti python specifici utilizzi, cosí provo a partire dalla lite e installare solo i pacchetti necessari?
Grazie e buona serata
ciao Andrea, temo che il problema sia che pi zero è arm6, mentre nodesource supporta solo le nuove versioni di arm. Il mio codice richiede almeno node12: purtroppo non ho un pi zero per fare qualche prova.
anche per l’incompatibilità di numpy è qualcosa di davvero strano: prova ad aggiornarlo con
pip install numpy --upgrade
. Tra l’altro numpy non lo chiamo direttamente, probabilmente serve a qualche libreria che utilizzo. L’elenco delle librerie che esplicitamente includo è quello su Github…grazie della risposta, adesso si spiega tutto. Proveró a recuperare un´altra scheda raspberry per la verifica. Ti ringrazio per l´aiuto e buona serata
curl -O https://unofficial-builds.nodejs.org/download/release/v14.17.0/node-v14.17.0-linux-armv6l.tar.gz
tar -xvf node-v14.17.0-linux-armv6l.tar.gz
cd cd node-v14.17.0-linux-armv6l/
sudo cp -R * /usr/local/
esegeundoli in sequenza nella shell di un raspberry viene installata la versione di pertinenza di Nodejs … testato su un 3b+ ppm install funziona correttamente
Ciao e stupendo lavoro Luca .., top
grazie Carlo!
luca hai ragione , ho provato a cambiare input tastiera al mac con unicode esadecimale e mi ha letto il qr giusto , ora mi domando come imposto input alla raspberry?
Salve e complimenti per il progetto.
Armeggio un po’ con arduino et similia e questo progetto mi ha molto incuriosito. Mi scuso se la domanda trova risposta in qualche riferimento che, al momento non ho trovato.
Quale hardware consiglia per non avere problemi con l’applicativo da lei creato?
Cordiali Saluti.
Buongiorno Giuseppe e grazie! Consiglio un Raspberry Pi 3 (A o B non importa) o superiore. In particolare io ho usato una scheda Pi 3A+. Attualmente la procedura per installare il software sulle schede Pi Zero è invece un po’ laboriosa e quindi non adotterei queste schede.
ciao Luca,
pensi sia possibile far girare la parte di acquisizione del greenpass tramite un modulo ESP32-CAM? potrebbe essere lei ad acquisire il qr e passarlo al validation server che ne restituisce la validità. sto cercando di capire come fare ma non ne vengo a capo. grazie dell’aiuto, qualora avrai voglia di darmelo.
ciao Stefano, non ho mai provato ma vedo che tutti i progetti di lettura qrcode si basano su questa libreria, solo che richiede una scheda con PSRAM e non ne ho nessuna al momento x fare qualche prova. Una volta letto il qrcode, per passarlo al validatorServer è sufficiente una chiamata HTTP quindi non dovresti avere problemi… solo ricordati di codificare il contenuto per evitare caratteri non validi
ciao Luca, anzitutto grazie per la risposta. la libreria che mi hai linkato è quella che ho identificato anche io per fare i miei test, ma al momento senza successo. continuo a provare 😉 buon lavoro!
ottimo, fammi sapere… se riesco a recuperare una devboard adatta magari ci gioco un po’ anche io 😉
Buonasera Luca
innanzitutto complimenti per il progetto, domani mi arriverà la raspberry cam che ho acquistato ma nel mentre ho iniziato a installare ex novo una installazione pulita di Raspbian completo su Pi3B.
Volevo chiederti come posso fare per mettere in avvio automatico i due pacchetti che devono essere eseguiti in sequenza, in passato ho generato qualcosa con Cron ma non sempre si avviava correttamente.
Grazie per un riscontro
ciao Paolo, grazie per i complimenti! Una soluzione “ingegnerizzata” per eseguire applicazioni Node è l’uso di PM2. Ti posso però dire che io sto usando due righe in cron (mettendo un po’ di delay in modo che l’applicazione python aspetti che quella node sia partita) e non mi da problemi.
Ciao, sarebbe possibile integrare la lettura di “Green pass valido” insieme al led verde e “Green pass non valido” insieme al led rosso?
ciao Federico, dove vorresti visualizzare la scritta? il progetto non ha display: se vuoi la scritta solo sul terminale è semplice aggiungerla al client Python.
In alternativa guarda il browserClient che ho implementato (lo trovi nello stesso repository Github): visualizza su una pagina web l’esito (e l’eventuale intestatario del greenpass)
Non riesco a passare mai la validazione del QR inquadrando il greenpass da raspicam. Ho provato anche ad aumentare la risoluzione all’interno dello script. Nella finestra di anteprima l’immagine si vede bene anche se non completamente a fuoco. Come faccio a controllare che PIL e zbarlight siano effettivamente funzionanti? Se uso la webapp e carico un immagine da file la validazione funziona perfettamente.
Era solo da aggiustare fisicamente il focus della Raspy. Ho aggiunto anche il TTS che oltre al led annuncia con un messaggio audio la validità o meno del certificato. Come uscita audio ho usato quella analogica in modo da attaccare un piccolo speaker da integrare all’interno del box
ottimo! grazie per l’aggiornamento
Ciao Luca,
ho seguito il tuo progetto raspberrypi-dgc, installando il validatorServer su un mio server Cloud. Dopo averlo avviato con npm, tutto ok e si mette in attesa. Se però invio una richiesta del tipo “http://151.xxx.xxx.xxx:3000/?dgc=HC1:6BFO……” mi dà risposta “INVALID: invalid distance too far back”. Cosa significa? Hai già verificato un problema del genere?
Grazie per la tua attenzione,
Ciao Cosimo, stai chiamando il validatorServer direttamente da browser? In tal caso devi fare l’urlencode della stringa del greenpass per evitare che caratteri non validi (es lo spazio) vengano rimossi. Se invece usi uno dei miei client lo fanno loro in automatico. L’errore che ottieni arriva dal primo passaggio (l’unzip) quindi significa che la stringa che arriva al validatorServer non è proprio valida…
Grazie Luca, hai ragione, ho verificato ed in effetti il browser elimina i caratteri “+”.
Buongiorno, sto provando a scaricare i codici per provare il progetto, sto usando un raspberryPi 4.
va tutto bene fino a quando arrivo a ” pip3 install opencv-contrib-python zbarlight”.
mi scarica tutto e inizia il “running setup.py bdist_whell for opencv-contrib-python …\”
da qua non mi va più avanti.
E’ più di un ora che che “…|” gira e non capisco se si è impiantato o sta lavorando.
Mi puoi aiutare a capire cosa c’è che non va o dove sbaglio.
Grazie
Buongiorno Massimiliano, la compilazione delle OpenCV su Raspberry impiega parecchio tempo, soprattutto se la SD è “lenta” o ci sono altri processi. Prova a vedere se i suggerimenti in questa issue possono aiutare (cmq sulla mia Pi3A ha impiegato quasi 2h)
Ciao Luca, effettivamente ha impiegato quasi 2 ore per l’installazione.
domani provo a collegare la pi camera e vedo se tutto è andato a buon fine.
grazie ancora per l’aiuto.
Ciao Sergio, ho provato anche io lo script che hai scritto, il lettore usb mi riporta tutte le lettere giuste (controllate una ad una con un’altra scansione del qrcode), il problema è che quando lo invia, mi restituisce “INVALID: unexpected end of file”.
cosa mi consigli di fare?
il green pass che sto leggendo è valido, quindi non capisco cosa c’è che non va.
grazie
Massimiliano, per essere sicuro che stai inviando la stringa corretta al server, aggiungi in questo punto una riga con
console.log(dgc);
. In questo modo il validatorServer ti stampa a video quello che riceve ed elabora: l’errore sembra infatti indicare che viene inviato un valore troncato…Non sono molto esperto ma dovo tanto lurkare sono riuscito a mettere giu’ un validatore funzionante con un pi4. Una domanda:
ma gli aggiornamenti che vedo su github come vanno applicati al progetto? VA eseguita una nuova “clonazione” e poi nuovamente npm install? oppure?
Ciao Giancarlo, puoi semplicemente utilizzare il comando
git pull
per aggiornare il tuo repository locale con le modifiche che vengono fatte sul server Github. Al termine conviene comunque lanciare unnpm install
per essere sicuro di avere anche tutti i moduli aggiornati.Ciao Luca,
complimenti per il progetto. Lo trovo molto semplice e funzionale.
Dal codice sembra che l’aggiornamento delle regole e dei certificati venga, di fatto, prima di attivare il server e le request quindi una tantum.
Ho dei dubbi su quando o ogni quanto debbano essere aggiornati tali dati.
Potresti darmi delle delucidazioni?
Grazie Giuseppe
grazie Giuseppe! Se ricordo bene l’app ufficiale aggiorna i dati ogni 24h, per ora non ho incluso un meccanismo simile nel validatorServer pensando di riavviarlo ogni tot ore. Sto però lavorando ad una funzionalità di “auto-refresh” delle configurazioni con una schedulazione che può essere scelta direttamente dall’utente
Ciao Luca, grazie per la celere risposta.
Da quello che ho constatato, l’app ufficiale, aggiorna i certificati e le regole durante il primo avvio o quando si svuotano i dati. In quelli successivi probabilmente solo le regole infatti le verifiche risultano molto più veloci.
Probabilmente tu conosci meglio i sorgenti, sarebbe interessante capire la logica dell’app ufficiale per integrarla nel progetto.
Se hai qualche info update us.
Grazie Giuseppe
da quello che vedo, almeno nell’ultima versione l’app VerificaC19 Android chiama un “worker” dell’SDK una volta al giorno per l’aggiornamento delle chiavi:
PeriodicWorkRequestBuilder(1, TimeUnit.DAYS)
Great Project,
only one thing.
I think the dgcpi-back.stl file in your GitHub is wrong.
Hi Andreas, why do you think the file is wrong? Can’t you open it with a slicer?
No No.
I can open the file with no problems, but the form is almost the as the front., only a bit less deeper.
It has the same holes for the Led´s and the camera. so i don´t know how to use this part to mount the pi.
you’re right! I uploaded the wrong, file, fixing now…
Ciao io non riesco ad avviare node app.js mi dice che manca il file clr.json ho provato con più installazioni di node. niente. grazie
Ciao Antonio, prova ora partendo da una installazione pulita… hanno aggiornato la libreria e “rotto” la compatibilità con il mio software (vedi anche questa issue). Ora dovrei aver risolto…
Ciao Luca grazie per il tuo progetto.
Sono riuscito a farlo andare su un pi2b partendo da raspbian lite e picam v1.3
Trovo solo problemi con i led: li ho collegati sul pin 6 (gnd) sul lato lungo del led e pin 3 e 5 ossia gpo 2 e 3 ma non si accendono. Se li collego invece sul 5v o 3.3v e gpo 2 e 3 rimangono fissi….
Sarebbe bello trovare in aggiornamento un display lcd di quelli piccoli o comunque un buzzer che avvisi con un bip se positivo e 3 bip se negativo… spero in nuove feature… sto pensando anche di prendere la pi camera 2.1 perché con la 1.3 non sempre prende al volo i codici qr. qualcuno che ha usato una cam usb sa dire cosa c’è da modificare e quale consiglia?
Ciao Alessandro, attento che il pin lungo del led è il positivo e va collegato al pin 3 e 5, mentre quello corto è la massa e va collegata al 6. Mettici però una resistenza altrimenti rischi di bruciarlo. Per l’aggiunta di un buzzer, buona idea! Infine per la webcam USB prova a guardare nelle issue di github, qualche utente aveva provato ad utilizzarla… sicuramente funziona con il client browser-based, mentre quello python va modificato perché usando la libreria picamera è per ora vincolato all’uso appunto della PiCAM.
ciao luca, ottimo progetto, visto i tempi che corrono… ho usato il client browser con le istruzioni che hai dato ma , si apre bene la finestra del browser ma mi dice che non ho i diritti per accedere alla telecamera. e ti volevo chiedere se , anche a pagamento, si può modificare il codice per utilizzarlo con una telecamera ip. grazie andrea
Ciao Andrea! Molto strano, al primo avvio il browser dovrebbe chiederti se autorizzi la webcam e via… se ti dice che non hai i diritti potrebbe essere qualche impostazione di sicurezza o antivirus che te la blocca.
Per quanto riguarda la camera ip, ti posso dire che un conoscente ha preso il mio codice (la parte server) e l’ha integrata in maniera molto semplice con una di quelle telecamere che già riconoscono i qrcode: essendo una chiamata HTTP è stato facile implementarla con l’SDK della camera. Alla fine ne è venuto un progetto commerciale e quindi non posso fornirti link o materiale. Se invece pensi ad una camera IP “generica”, quindi senza funzione di riconoscimento qrcode, puoi semplicemente “catturare” il flusso video nel client pyton via RTSP. Al momento non ho una camera IP per fare qualche prova ma cerco di recuperarla.
Si, vorrei catturare l’immagine con una telecamera ip. Ho il flusso rtsp di una telecamera e vorrei usare quello però io non so come modificare il codice.
tu puoi darmi una mano?
purtroppo al momento non ho una camera IP quindi non riuscirei a testare nulla… mi spiace
Ciao a tutti,
Intanto grazie Luca. Il mio progetto era far leggere tutto tramite uno scanner qrcode e una stampa dell’esito tramite stampante. Tuttavia provando con il Raspberry Model B prima versione non funziona. sono riuscito a far partire il validator e provando con il semplice script di Sergio Bucci ottengo un errore di sintassi che dovrei aver risolto(” e indentazione), tuttavia incollando e premendo invio non succede nulla. Mi viene quasi il dubbio che il mio raspberry non ce la faccia a elaborare la richiesta. Ho preso un raspberry pi 4, vi saprò dire piu avanti se funziona tutto regolarmente.
Buongiorno, progetto interessantissimo davvero, mi chiedevo se fosse possibile interfacciare il raspberry con un relè che chiude un contatto normalmente aperto, questo perchè in caso di green pass valido il raspberry al posto del led verde possa resittuire l’apertura di una porta sesamo o di un tornello ad esempio.
Grazie mille
Grazie! Si è molto semplice, si può sostituire il led con un relay a 3.3V (pilotabile da rasbperry) e il gioco è fatto