57

What's Inside the EU Green Pass QR Code?

 2 years ago
source link: https://gir.st/blog/greenpass.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

What's Inside the EU Green Pass QR Code?Home | Blog | Green Pass Analysis

What's Inside the EU Green Pass QR Code?

Here in Austria, you need to be either vaccinated against, tested negative for, or have recovered from COVID-19 to go to the pub (or pretty much everywhere) right now. If you don't want to carry around your paperwork proving one of those, you can alternatively show your Green Pass QR code to be let in.

As a privacy concious person, I wanted to know what details I give away when I let my server scan my code.

greenpass-demo.pngA Green Pass code, generated from fictitious data

This is what a Green Pass looks like. Quite large for a QR code, but given that it is supposed to store more than a hyperlink, that's to be expected. Let's decode it.

t@thi3nkpad ~ % zbarimg --raw greenpass.png

HC1:NCFOXN%TS3DH3ZSUZK+.V0ETD%65NL-AH-R6IOO6+IUKRG*I.I5BROCWAAT4V22F/8X*G3M9JUPY0BX/KR96R/S09T./0LWTKD33236J3TA3M*4VV2 73-E3GG396B-43O058YIB73A*G3W19UEBY5:PI0EGSP4*2DN43U*0CEBQ/GXQFY73CIBC:G 7376BXBJBAJ UNFMJCRN0H3PQN*E33H3OA70M3FMJIJN523.K5QZ4A+2XEN QT QTHC31M3+E32R44$28A9H0D3ZCL4JMYAZ+S-A5$XKX6T2YC 35H/ITX8GL2-LH/CJTK96L6SR9MU9RFGJA6Q3QR$P2OIC0JVLA8J3ET3:H3A+2+33U SAAUOT3TPTO4UBZIC0JKQTL*QDKBO.AI9BVYTOCFOPS4IJCOT0$89NT2V457U8+9W2KQ-7LF9-DF07U$B97JJ1D7WKP/HLIJLRKF1MFHJP7NVDEBU1J*Z222E.GJF67Z JA6B.38O4BH*HB0EGLE2%V -3O+J3.PI2G:M1SSP2Y3D38-G9C+Q3OT/.J1CDLKOYUV5C3W1A:75S4LB:6REPKM3ZYO4+QDNDLT2*ESLIH

Well, that's ... something. What we're looking at there is a Base45-encoded, compressed, signed binary data structure. The group who designed the EU green pass have published the QR Code specification, that goes into detail about the which and why of the technologies chosen, but in short: it's heavily optimized for size and reliability.

Looking at the hexdump

t@thi3nkpad ~ % zbarimg --raw greenpass.png|cut -b5-|tr -d '\n'|base45 --decode|openssl zlib -d|xxd

00000000: d284 4d  ..M
00000010: a059 0133   .Y.3
00000020:   
00000030:   
00000040:   
00000050:   
00000060:   
00000070:   
00000080:   
00000090:   
000000a0:   
000000b0:   
000000c0:   
000000d0:   
000000e0:   
000000f0:   
00000100:   
00000110:   
00000120:   
00000130:   
00000140: 58 40  X@
00000150:   
00000160:   
00000170:   
00000180:                    

Using a little bit of python, we can extract the following data from the payload, which I annotated by consulting the Green Pass schema.

{-260: {1: {'dob': '1998-02-26', date of birth
            'nam': {'fn': 'Musterfrau-Gößinger', family name
                    'fnt': 'MUSTERFRAU<GOESSINGER',
                    'gn': 'Gabriele', given name
                    'gnt': 'GABRIELE'},
            'v': [{'ci': 'URN:UVCI:01:AT:10807843F94AEE0EE5093FBC254BD813#B', certificate ID
                   'co': 'AT', country of vaccination
                   'dn': 1, doses received
                   'dt': '2021-02-18', date of vaccination
                   'is': 'Ministry of Health, Austria', cert issuer
                   'ma': 'ORG-100030215', vaccine manufacturer
                   'mp': 'EU/1/20/1528', vaccine product id
                   'sd': 2, total number of doses
                   'tg': '840539006', targeted disease (COVID-19)
                   'vp': '1119349007'}], vaccine or prophylaxis
            'ver': '1.2.1'}}, schema version
 1: 'AT', QR code issuer
 4: 1624458597, QR code expiry
 6: 1624285797} QR code generated

As you can see, 23 year-old Gabriele was vaccinated in February, once, with BioNTech/Pfizer's Comirnaty. What is not included is the date during which she is considered immune. Those are calculated from the number of shots received and the date of vaccination, as well as the circumstances (going to a restaurant vs. going to work, for example) by the scanner app. Apart from the name/manufacturer of the received vaccine, there is no superfluous data inside, so the QR code is not a privacy nightmare, as some have feared.

example of tested person's data

{-260: {1: {'dob': '1998-02-26', 
            'nam': {'fn': 'Musterfrau-Gößinger', 
                    'fnt': 'MUSTERFRAU<GOESSINGER',
                    'gn': 'Gabriele', 
                    'gnt': 'GABRIELE'},
            't': [{'ci': 'URN:UVCI:01:AT:B5921A35D6A0D696421B3E2462178297#I', 
                   'co': 'AT', 
                   'is': 'Ministry of Health, Austria', 
                   
                   'nm': 'Roche LightCycler qPCR', 
                   
                   'ma': '1232', 
                   'sc': '2021-02-20T12:34:56Z', 
                   'tc': 'Testing center Vienna 1', 
                   'tg': '840539006', 
                   'tr': '260415000', 
                   'tt': 'LP6464-4'}], 
            'ver': '1.2.1'}}, 
 1: 'AT', 
 4: 1624458597, 
 6: 1624285797} 

example of recovered person's data

{-260: {1: {'dob': '1998-02-26', 
            'nam': {'fn': 'Musterfrau-Gößinger', 
                    'fnt': 'MUSTERFRAU<GOESSINGER',
                    'gn': 'Gabriele', 
                    'gnt': 'GABRIELE'},
            'r': [{'ci': 'URN:UVCI:01:AT:858CC18CFCF5965EF82F60E493349AA5#K', 
                   'co': 'AT', 
                   'df': '2021-04-04', 
                   'du': '2021-10-04', 
                   'fr': '2021-02-20', 
                   'is': 'Ministry of Health, Austria', 
                   'tg': '840539006'}], 
            'ver': '1.2.1'}}, 
 1: 'AT', 
 4: 1624458597, 
 6: 1624285797} 

To check out the data on your own green pass, check out greenpass.py. It takes the PDF from gruenerpass.gv.at or PNG of the QR code itself on the command line, and prints out all the data, annotated with the above mentioned schema.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK