paint-brush
How to Decode Your Own EU Vaccination Green Pass With a Few Lines of Pythonby@tobsch
75,431 reads
75,431 reads

How to Decode Your Own EU Vaccination Green Pass With a Few Lines of Python

by Tobias SchlottkeJuly 14th, 2021
Read on Terminal Reader
Read this story w/o Javascript

Too Long; Didn't Read

Find out how to decode the QR code in your EU Vaccination Passport (Green Pass) using Python. Find out which data is encoded inside

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coin Mentioned

Mention Thumbnail
featured image - How to Decode Your Own EU Vaccination Green Pass With a Few Lines of Python
Tobias Schlottke HackerNoon profile picture

The EU Vaccination passport has arrived! The company UBIRCH has worked around the clock for the past few weeks to ensure millions of Germans were able to enjoy a summer of free movement.

The vaccination certificate looks like a simple QR code on paper yet a lot of technology went into making sure to secure the personal data, make it accessible to only authorized users, and also hard to fake. 

In a podcast geared towards CTOs, Matthias Jugel, the CTO of UBIRCH shared what went into the technology and explained how to simply decode the content of the QR-Code.


The EU Vaccine Program

The German vaccination pass is based on the protocols defined by the European Union regarding vaccine certificates for its member states. 

When you get your shot you create a little dataset which contains your personal information, your name, and your birth date, for example, and also some information about the actual vaccination: the manufacturer; product id of the shot; the date when you got your shot and which shot in a series of doses.

The EU also has protocols on how this data set should be handled. It needs to be put into a binary representation which is then signed using a cryptographic key material. Anyone with the public key can now verify that it's authentic.

This binary representation  is then compressed and encoded into base-45- which is known to be very efficient in combination with QR codes. The base-45 text representation is then put into a QR code which is printed and has your code and your pass. The complete chain is: base45 > zlib > COSE object -> CBOR

This method is different from a JW token because it's a bit smaller. A JWT is encoded base-64, purely text-based and it's not compressed in itself. This means it cannot contain as much information in the same amount of data basically so it's very big in the end.

Still, someone has to take care of converting the dataset into a signed piece of data. Therefore, UBIRCH provides a service in which they receive the data, transform it, sign it, and then hand back something that can be either printed in a QR code or printed as a PDF document. This is all done through the vaccination centers.


Decoding your own Green Pass

Even though legally only authorised personnel should be checking the contents of the QR code, you can still check what's inside your own QR code from a technical standpoint. You won't be able to perform signature verification though as access to the public keys is not officially available. So the below code is only for nerds who want to know what data is encoded in their QR code.



1. Use a QR-Code reader to get the content of your own QR-Code. Browser-based one is here:

Here is a sample QR code of a fictional person that we will be using for this example

HC1:6BFNX1:HM*I0PS3TLU.NGMU5AG8JKM:SF9VN1RFBIKJ:3AXL1RR+ 8::N$OAG+RC4NKT1:P4.33GH40HD*98UIHJIDB 4N*2R7C*MCV+1AY
3:YP*YVNUHC.G-NFPIR6UBRRQL9K5%L4.Q*4986NBHP95R*QFLNUDTQH-GYRN2FMGO73ZG6ZTJZC:$0$MTZUF2A81R9NEBTU2Y437XCI9DU 4S3N%JRP:HPE3$ 435QJ+UJVGYLJIMPI%2+YSUXHB42VE5M44%IJLX0SYI7BU+EGCSHG:AQ+58
CEN RAXI:D53H8EA0+WAI9M8JC0D0S%8PO00DJAPE3 GZZB:X85Y8345MOLUZ3+HT0TRS76MW2O.0CGL EQ5AI.XM5 01LCWBA.RE.-SUYH+S7SBE0%B-KT+YSMFCLTQQQ6LEHG.P46UNL6DA2C$AF-SQ00A58HYO5:M8 7S$ULGC-IP49MZCS
U8ST3HDRJNPV3UJADJ9BVV:7K13B4WQ+DCTEG4V8OT09797FZMQ3/A7DU0.3D148IDZ%UDR9CYF

2. Create a Python file with the following code and save as decode.py

#! /usr/bin/env python3
import json
import sys
import zlib
 
import base45
import cbor2
from cose.messages import CoseMessage
 
payload = sys.argv[1][4:]
print("decoding payload: "+ payload)
 
# decode Base45 (remove HC1: prefix)
decoded = base45.b45decode(payload)
 
# decompress using zlib
decompressed = zlib.decompress(decoded)
# decode COSE message (no signature verification done)
cose = CoseMessage.decode(decompressed)
# decode the CBOR encoded payload and print as json
print(json.dumps(cbor2.loads(cose.payload), indent=2))

3. Install all libraries required to use the example code:

pip3 install cryptography==2.8
pip3 install cose
pip3 install cbor2
pip3 install base45

4. Execute the python file

python3 decode.py 'HC1:6BFNX1:HM*I0PS3TLU.NGMU5AG8JKM:SF9VN1RFBIKJ:3AXL1RR+ 8::N$OAG+RC4NKT1:P4.33GH40HD*98UIHJIDB 4N*2R7C*MCV+1AY3:YP*YVNUHC.G-NFPIR6UBRRQL9K5%L4.Q*4986NBHP95R*QFLNUDTQH-GYRN2FMGO73ZG6ZTJZC:$0$MTZUF2A81R9NEBTU2Y437XCI9DU 4S3N%JRP:HPE3$ 435QJ+UJVGYLJIMPI%2+YSUXHB42VE5M44%IJLX0SYI7BU+EGCSHG:AQ+58CEN RAXI:D53H8EA0+WAI9M8JC0D0S%8PO00DJAPE3 GZZB:X85Y8345MOLUZ3+HT0TRS76MW2O.0CGL EQ5AI.XM5 01LCWBA.RE.-SUYH+S7SBE0%B-KT+YSMFCLTQQQ6LEHG.P46UNL6DA2C$AF-SQ00A58HYO5:M8 7S$ULGC-IP49MZCSU8ST3HDRJNPV3UJADJ9BVV:7K13B4WQ+DCTEG4V8OT09797FZMQ3/A7DU0.3D148IDZ%UDR9CYF'

5. This is what the output would look like:

{
  "1": "DE", // issuing country
  "4": 1655209933, // expires at
  "6": 1623673933, // issued at
  "-260": { 
    "1": {
      "v": [
        {
          "ci": "URN:UVCI:01DE/IZ12345A/21E0JXD7UQY6ECLM3WT7YF#8",
          "co": "DE",
          "dn": 2,
          "dt": "2021-04-01",
          "is": "Robert Koch-Institut",
          "ma": "ORG-100031184",
          "mp": "EU/1/20/1507",
          "sd": 2,
          "tg": "840539006",
          "vp": "1119349007"
        }
      ],
      "dob": "1964-08-12",
      "nam": {
        "fn": "Mustermann",
        "gn": "Erika",
        "fnt": "MUSTERMANN",
        "gnt": "ERIKA"
      },
      "ver": "1.0.0"
    }
  }
}


The Verification of Vaccination Passes - Offline

However, the actual verification can all be done offline - to fit with the requirements of the EU. The corona apps deal with the verification of such passes - without needing the internet. Verification is done entirely through the phone.

 The apps get the public keys and verify the signature, and then depending on the intended usage, they might present you the content of the QR code - the data that's actually in there.

There are 2 types of apps available.

The official app for authorised personnel and the official app for the public.

CovPass Check App for Authorised Personnel 

The official app was made to allow free travel in the EU. It is meant to be used when you cross a border or when checked abroad by police or by somebody who would like to know whether you're allowed to be there. 

This information contains personal data and that is why the official app - that can access all the data contained in the QR code is for authorised personnel only. 

The official CovPass app for Public Use

You can get an authorised app from the app store which will tell you whether the scanned QR code is valid. The idea behind it is to present as little personal information as possible, to protect the privacy of everyone involved. 

Using Blockchain to verify Vaccine Passes - Online

For their pilot-solution which has been applied in two German counties, UBIRCH used blockchain technology to make vaccine passes verifiable for authenticity and integrity in a decentral manner. 

    1. People in the vaccination center fill in a web form with their details: name, date of birth, vaccination date, what type - all the data that the EU wants to collect.
    2. Upon submit, this information is hashed together with a salt - making it anonymous
    3. The hash is sent to the backend where it is anchored in the blockchain
    4. A URL is generated containing all the data provided in the webform
    5. A QR is also created which when scanned will display the data captured by the webform
    6. If someone wants to just validate the URL, they can go to the URL, it is decoded and a hash is sent to the server and a response is sent back whether it's valid with a signature.

UBIRCH still uses blockchain technology in other use cases. However, in close collaboration with the customer and in line with final EU requirements another approach for the implementation of the digital COVID-certificate in Germany was chosen.

This article was based on an alphalist podcast episode. The alphalist podcast features interviews of CTOs and other technical leadership figures and topics range from technology to management.

Guests from leading tech companies share their best practices and knowledge.

The goal is to support other CTOs on their journey through tech and engineering, inspire and allow a sneak-peek into other successful companies to understand how they think and act. Get awesome insights into the world‘s top tech companies, personalities and trends by listening today on Apple, Spotify, Google, Deezer and more.

If you are a CTO of tech-product company, perhaps you would be interested in joining alphalist -an exclusive CTO network? Reach out to us for more information.