Rynek lotniczy w pandemii. Jak wyglądała weryfikacja szczepień przeciwko COVID-19 od strony IT?
Wybuch pandemii COVID-19 całkowicie odmienił dotychczasowe życie oraz sposób prowadzenia biznesu. Świat stanął przed wyzwaniem, w którym – z jednej strony – musiały zostać stworzone warunki do powstrzymywania rozpowszechniania się wirusa, a z drugiej – powinno się umożliwić normalne funkcjonowanie społeczeństwa. Jednym z rozwiązań, które miały na celu powstrzymywanie rozpowszechniania się wirusa było stworzenie systemu do weryfikacji, czy dana osoba jest zaszczepiona przeciwko COVID-19.
Komisja Europejska oraz kraje UE zdecydowały się na wdrożenie jednolitego systemu do przedstawiania dowodu szczepienia przeciwko koronawirusowi (między innymi w branży lotniczej). Efektem tego było powstanie EU Digital COVID Certificate oraz organizacja zrzeszająca programistów o nazwie EU Digital Green Certificates.
W związku z tym Lufthansa Group stworzyła projekt o nazwie Digital Covid Certificate Handler. Projekt ten wykorzystuje EU Digital COVID Certificate i służy weryfikacji dowodu szczepienia.
Niniejszy artykuł opisuje zasadę działania tego projektu.
Spis treści
Opis procesu
Digital Covid Certificate Handler, jako dane wejściowe otrzymuje QR Code certyfikatu szczepionkowego w postaci BASE45, a następnie przetwarza go do postaci JSON Document. Aby lepiej zrozumieć ten proces sprawdźmy, jak wygląda tworzenie QR Code certyfikatu szczepionkowego:
https://github.com/ehn-dcc-development/hcert-spec
Powyższa ilustracja pokazuje proces powstawania QR Code na podstawie danych wygenerowanego certyfikatu COVID.
W pierwszym kroku dane na temat zaszczepionej osoby przekształcane są do formatu JSON. Następnie JSON przekształcany jest na postać COBR. W trzecim kroku dokument COBR jest podpisywany kluczem prywatnym, w wyniku którego powstaje COSE Document. Następnie dane są kompresowane za pomocą ZLIB oraz mechanizmu kompresji Deflate. Kompresja ta jest stosowana w celu zmniejszenia rozmiaru dokumentu oraz zapewnienia niezawodności procesu odczytu. Kolejnym krokiem jest przekształcenie danych na postać Base45. Kodowanie Base45 używane jest na potrzeby lepszej obsługi starszych urządzeń obsługujących dane ASCII[7]. Ostatnim krokiem jest dodanie identyfikatora kontekstu „HC1:” i wygenerowanie kodu QR. W przyszłych wersjach specyfikacji certyfikatu COVID, które mają wpływ na kompatybilność wsteczną, zostanie zdefiniowany nowy identyfikator kontekstu.
Na potrzeby tego artykułu skorzystamy z danych testowych EU Digital Green Certificates.
Dane, które przetwarzamy zawierają prefix HC1, tak więc pobieramy dane testowe:
"PREFIX": "HC1:6BF+70790T9WJWG.FKY*4GO0.O1CV2 O5 N2FBBRW1*70HS8WY04AC*WIFN0AHCD8KD97TK0F90KECTHGWJC0FDC:5AIA%G7X+AQB9746HS80:54IBQF60R6$A80X6S1BTYACG6 M+9XG8KIAWNA91AY%67092L4WJCT3EHS8XJC$+DXJCCWENF6OF63W5NW6WF6%JC QE/IAYJC5LEW34U3ET7DXC9 QE-ED8%E.JCBECB1A-:8$96646AL60A60S6Q$D.UDRYA 96NF6L/5QW6307KQEPD09WEQDD+Q6TW6FA7C466KCN9E%961A6DL6FA7D46JPCT3E5JDLA7$Q6E464W5TG6..DX%DZJC6/DTZ9 QE5$CB$DA/D JC1/D3Z8WED1ECW.CCWE.Y92OAGY8MY9L+9MPCG/D5 C5IA5N9$PC5$CUZCY$5Y$527B+A4KZNQG5TKOWWD9FL%I8U$F7O2IBM85CWOC%LEZU4R/BXHDAHN 11$CA5MRI:AONFN7091K9FKIGIY%VWSSSU9%01FO2*FTPQ3C3F"
1. Na samym początku usuwamy prefix HC1:
6BF+70790T9WJWG.FKY*4GO0.O1CV2 O5 N2FBBRW1*70HS8WY04AC*WIFN0AHCD8KD97TK0F90KECTHGWJC0FDC:5AIA%G7X+AQB9746HS80:54IBQF60R6$A80X6S1BTY ACG6M+9XG8KIAWNA91AY%67092L4WJCT3EHS8XJC$+DXJCCWENF6OF63W5NW6WF6%JC QE/IAYJC5LEW34U3ET7DXC9 QE-ED8%E.JCBECB1A-:8$96646AL60A60S6Q$D.UDRYA 96NF6L/5QW6307KQEPD09WEQDD+Q6TW6FA7C466KCN9E%961A6DL6FA7D46JPCT3E5JDLA7$Q6E464W5TG6..DX%DZJC6/DTZ 9 QE5$CB$DA/D JC1/D3Z8WED1ECW.CCWE.Y92OAGY8MY9L+9MPCG/D5 C5IA5N9$PC5$CUZCY$5Y$527B+A4KZNQG5TKOWWD9FL%I8U$F7O2IBM85CWOC%LEZU4R/BXHDAHN 11$CA5MRI:AONFN7091K9FKIGIY%VWSSSU9%01FO2*FTPQ3C3F
2. W następnym kroku dekodujemy uzyskaną wartość. Jak już wcześniej zostało wspomniane, dane dostarczone są w formacie BASE45. Do dekodowania została użyta biblioteka Base45 z projektu: https://github.com/ehn-dcc-development/base45-java.
Wystarczy dodać bibliotekę do swojego projektu i użyć metody decode(String src), którego parametrem jest Certificat COVID w formacie BASE45. Rezultatem tego działania jest tablica bajtów:
3. Kolejnym krokiem jest zdekompresowanie rezultatu za pomocą algorytmu ZLib. W tym wypadku korzystamy z biblioteki Apache Common Compress. Za pomocą tej biblioteki, możemy zdekompresować tablice bajtów i rezultat przepisać do CompressorInputStream, który dziedziczy po InputStream.
Ostatnim krokiem jest przepisanie CompressorInputStream na tablicę bajtów. W rezultacie dostajemy tablicę bajtów reprezentującą obiekt COSE:
4. Teraz musimy przekształcić COSE do struktury CBOR. W tym celu użyjemy biblioteki COSE-JAVA. Najpierw przekształcamy tablicę bajtów do obiektu Sign1Message:
Za pomocą Sig1Message możemy stworzyć CBORObject, który reprezentuje strukturę danych CBOR:
Gdy sprawdzimy zawartość stworzonego przez nas obiektu, możemy zauważyć, że zawiera dane certyfikatu szczepionkowego:
Teraz wystarczy przepisać CBORObject na dokument JSON:
Efektem działania jest JSON, zawierający dane na temat:
{"1":"DE","4":1643356073,"6":1622316073,"-260":{"1":{"v":[{"dn":2,"ma":"ORG-100031184","vp":"1119349007","dt":"2021-05-29","co": "DE","ci":"URN:UVCI:01DE/IZ12345A/5CWLU12RNOB9RXSEOP6FG8#W","is":"Robert Koch-Institut","mp":"EU/1/20/1507","sd":2, "tg":"840539006"}],"nam":{"fnt":"MUSTERMANN","fn":"Mustermann","gnt":"ERIKA","gn":"Erika"},"dob":"1964-08-12","ver":"1.0.0"}}}
Dokumentację struktury danych certyfikatu szczepionkowego możemy znaleźć na tej stronie.
Walidacja certyfikatu
W poprzednim rozdziale został opisany proces przekształcania BASE45 do struktury JSON. Kolejnym krokiem jest sprawdzenie, czy certyfikat został wygenerowany przez oficjalną instytucję zdrowotną.
1. Najpierw musimy pobrać oficjalną listę: Trusted List, wykorzystywaną przez EU Digital COVID Certificate. Trusted list dla danych testowych pobieramy z tej strony, a dla danych produkcyjnych z tej strony.
Po wejściu na stronę możemy pobrać JSON zawierający listę obiektów Certificate, który posiada pola:
„kid”,”timestamp”, „country”, „certificateType”, „thumbprint”, „signature”, „rawData”.
Za pomocą pola kid możemy zidentyfikować, który obiekt Certificate przypisany jest do podanego EU Digital COVID Certificate. Pole rawData zawiera dane, dzięki którym możemy stworzyć klucz publiczny wykorzystywany do weryfikacji podanego EU Digital COVID Certificate.
2. Jak już wcześniej wspomniano, jednym z etapów procesu przetwarzania EU Digital COVID Certificate jest przepisanie go do struktury COSE. Według dokumentacji standardu COSE[2], jednym z elementów umieszczonym w header jest pole „kid”. Tak, więc musimy pobrać wartość pola kid naszego certyfikatu szczepionkowego. Robimy to za pomocą obiektu Sign1Message:
W podanym przykładzie wartość kid wynosi „DEsVUSvpFAE=”. Gdy porównamy to z zawartością z tej strony możemy zauważyć, że podany kid jest przypisany do:
{"certificateType": "DSC", "country": "DE", "kid": "DEsVUSvpFAE=", "rawData": "MIIGXjCCBBagAwIBAgIQXg7NBunD5eaLpO3Fg9REnzA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFl(...)wiPYMwx2ZP+mIf1QHu/nyDtQ=", "signature": "MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIIF(...)J1XcgrY1bmS3TlRV0AAAAAAAA", "thumbprint": "0c4b15512be914016eea23da5eae865c63bbb9046dd4af409e230202c6a57477", "timestamp": "2021-06-05T11:43:55+02:00"}, {"certificateType": "DSC", "country": "DE", "kid": "DJANd2eecu8=", "rawData": "MIIGSTCCBAGgAwIBAgIQa3cXKurGOl5f+wSyOCHwOjA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFl(...) OJ9BuaEVTfDi88KDCb/b/u+JCX/qKu2BJBqDTH563LAuk2qoIaUigw2O94bTCyqYDVJFp0GEc=", "signature": "MIAGCSqGSIb3DQEHAqCAMIACAQExDTALBglghkgBZQMEAgEwgAYJKoZIhvcNAQcBAACggDCCBSkw(...) 87PB/eCLWI5fH2SpOAJCwqCSGW6n+XjqmqT8p0ee+IAAAAAAAA", "thumbprint": "0c900d77679e72ef4bb7d36aeda9552ab8d13a5992f40c634aa83aef486435ba", "timestamp": "2021-11-30T17:50:48+01:00"}
3. Teraz wystarczy wygenerować klucz publiczny na podstawie rawData. Najpierw przepisujemy rawData do tablicy bajtów:
A następnie generujemy klucz publiczny:
Należy pamiętać, że metoda generateCertificate jako parametr przyjmuje obiekt typu InputStream, dlatego wcześniej musimy przepisać wygenerowaną tablicę bajtów do InputStream.
4. Ostatnim krokiem jest weryfikacja podpisu Certyfikatu COVID na podstawie stworzonego Public Key. W tym celu ponownie korzystamy z Sign1Message:
Jeżeli podpis jest poprawny, otrzymujemy wartość true.
Podsumowanie
EU Digital COVID Certificate znacznie ułatwił dostosowanie się rynku lotniczego do warunków wynikających z wybuchu pandemii COVID-19. Imponujące jest to, że Unia Europejska w tak krótkim czasie była w stanie stworzyć standard generowania oraz przetwarzania certyfikatów szczepionkowych, który obejmuje wszystkie kraje członkowskie. Dokładna i przejrzysta dokumentacja oraz rozwój stworzonego na podstawie EU Digital Covid Cerficate oficjalnego projektu GitHub, znacznie ułatwia tworzenie projektów odczytujących dane z certyfikatów szczepionkowych. Dzięki temu Lufthansa Group mogła sprawnie zautomatyzować walidację certyfikatów, tworząc projekt Digital Covid Certificate Handler.
Digital Delivery Lab (DDL) to wyjątkowa inicjatywa, której głównym celem jest digitalizacja procesów obsługi pasażera w ramach linii lotniczych Lufthansa Group. DDL to zespół wysokiej klasy profesjonalistów – programistów, architektów i analityków, którzy – działając w ścisłej współpracy – odpowiedzialni są za spójną realizację nawet najbardziej skomplikowanych projektów.
Zdjęcie główne pochodzi z unsplash.com.