If you receive a vaccine shot against the coronavirus within the EU, you might get a digital certificate in the form of a QR code to prove your vaccination status. The QR code can be verified with specialized apps, like the CovPass Check app.
If you are like me, you want to decode the QR code yourself and know what information is stored. The technical details are published on the webpage of the European Commission. Let’s assume you have a cropped photo of your QR code and have installed the following python packages.
$ pip install cbor2 cose qrtools base45
To show the information, we need to perform the following steps:
- First, we need to parse the QR code image (
- The text of the QR code contains a human-readable version identifier,
HC1followed by a colon. To proceed, we chop off this part.
- The actual binary data is base45 encoded and needs to be decoded.
- The COSE message itself is ZLib compressed and needs to be decompressed before we can,
- Finally, parse the COSE message and its payload.
The following script illustrates the decoding procedure.
FILE_PATH = "photo_of_the_qr_code.jpg" from argparse import ArgumentParser from zlib import decompress from qrtools import QR from base45 import b45decode from cose.messages import CoseMessage from cbor2 import loads import json # Parse the QR code photo qr = QR() qr.decode(FILE_PATH) qr_data = qr.data.encode() # Remove version version = qr_data[:3] print("Version:", version) raw = qr_data[4:] # Decode Base 45 decoded = b45decode(raw) # Decompress decompressed = decompress(decoded) # Unpack message msg = CoseMessage.decode(decompressed) # Decode payload payload = loads(msg.payload) # Print print("Payload:") print(json.dumps(payload, indent=2))
Please note that for the sake of clarity, there is no error handling the above script.