29.10.2021 16:48

EU Digital Green Certificate: Was gilt eigentlich bei uns?

Nachdem der digitale grüne Pass gerade in den Medien ist, und ich für den Standard den Erklärbären mache, will ich hier ein paar technische Informationen dokumentieren, die für einen Zeitungsartikel dann doch zu technisch sind.

Erstmal: die Technik hinter dem Grünen Pass ist keine Hexerei. Da sind keine magischen oder geheimen Zutaten dabei. Das ganze Projekt wurde extrem offen entwickelt und dokumentiert und baut auf einer Reihe von offenen Standards auf. Auch wurde ganz viel der Software, die in diesem Kontext geschrieben wurde, als Open Source auf github veröffentlicht.

Ich hab mir im Sommer schon mal privat angeschaut, wie so ein QR code aufgebaut ist. Kurz zusammengefasst geht das so:

  • Scannt man den QR-Code, bekommt man einen ASCII String
  • Der wird per base45 in eine Folge von Bytes konvertiert
  • Das wird per zlib entpackt
  • Jetzt haben wir eine CBOR-Struktur (quasi JSON, aber binär kodiert)
  • Diese ist per COSE Standard signiert
  • Und im signierten Teil sind dann die eigentlichen Datenfelder, die die Impfung beschreiben

Nachdem jetzt berichtet wurde, dass mit dem Schlüssel von Nord-Mazedonien sinnlose Grüne Pässe signiert wurde, wollte ich nachschauen, wie Österreich reagiert hat.

Auch die Implementation Österreichs ist ausgiebig auf Github dokumentiert. Man findet sehr schnell, dass die Liste der Digitalen Schlüssel, deren Unterschrift von unserer "Green Check" App anerkannt wird, per https://dgc-trust.qr.gv.at/trustlist verteilt wird.

Wie kann man sich das File mit Linux Bordmitteln anschauen?

$ wget https://dgc-trust.qr.gv.at/trustlist

Da meine toolchain für cbor ziemlich leer ist, hab ich rq installiert, damit kann ich dann per

$ cat trustlist | rq -c -J | jq .c > trustlist.json

in die JSON-Welt wechseln. Das ergibt einen JSON Array von Hashes, wobei "c" das Zertifikat im DER Format und "i" die Keyid ist. Da JSON keine binären Daten enthalten kann, hat rq das jeweils als Array von Bytes kodiert. Mit einem kleinen Perl-Script lassen sich die DER Files extrahieren:

#!/usr/bin/perl -w

use strict;
use JSON;

my $json = JSON->new->allow_nonref;
my $text = "";

while (<>) { $text .= $_ };

my $certs = $json->decode( $text );
my ($c, $i, $cstr, $istr);
foreach my $cert (@$certs)  {
        $i = $cert->{i};
        $c = $cert->{c};

        $istr = join("", map { sprintf("%02x",$_) } @$i);
        $cstr = pack("C*", @$c);
        open(F, ">$istr.der"); print F $cstr; close(F);
}

 Dank openssl kann man die DER Files lesbar machen:
for f in *der ; do openssl x509 -in $f -inform DER -noout -text > $f.text; done

Der Public Key, mit dem Österreich die hiesigen Grünen Pässe signiert, ist dieser:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            01:79:cc:f8:be:3b:7e:60:5c:7b
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = AT, O = BMSGPK, serialNumber = 001, CN = AT DGC CSCA 1
        Validity
            Not Before: Jun  2 13:45:24 2021 GMT
            Not After : Jun  2 13:45:24 2023 GMT
        Subject: C = AT, O = BMSGPK, serialNumber = 001001, CN = AT DGC DSC 1
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:60:4d:b8:a8:82:a6:75:c7:d1:59:48:76:4e:a9:
                    25:91:f6:7a:9f:23:41:a5:7e:15:1d:e2:cc:c5:f1:
                    65:f2:b9:10:f1:99:2e:d1:b7:27:1f:93:99:5d:c9:
                    24:4a:df:ad:2a:cf:85:19:9f:6d:28:9d:55:b4:d0:
                    e6:79:d9:4b:eb
                ASN1 OID: prime256v1
                NIST CURVE: P-256

 Ein "fgrep -h Subject: *text" zeigt alle 203 Schüssel, denen Österreich aktuell vertraut. Aus welchen Ländern kommen diese?

$ fgrep -h Subject: *text | perl -p -e 's/.* C = (\w+).*/$1/' | sort -u | xargs echo 
AD AL AM AT BE BG CH CY CZ DE DK EE ES FI FO FR GB GR HR HU IE IL IS IT LI LT LU LV
MA MC MK MT NL NO PA PL PT RO SE SI SK SM TR UA VA

 Viele Staaten verwenden nur einen Schlüssel, manche aber auch mehrere:

$ fgrep -h Subject: *text | perl -p -e 's/.* C = (\w+).*/$1/' | sort | uniq -c| sort -rn
     57 DE
     32 FR
     21 ES
     12 NL
     12 CH
      7 GB
      6 MT
      6 LU

Und was ist mit Mazedonien? Der Schlüssel mit CC = MK wurde erst gestern erzeugt. Man hat also reagiert, und den alten Schlüssel widerrufen (und damit alle von ihm signierten Grünen Pässe ungültig gemacht) und durch einen neuen ersetzt.

Zusammenfassung: Das System ist ausgesprochen transparent. Ich habe für diese Analyse kein Insiderwissen gebraucht.

Verfasst von: Otmar Lendl