https://gir.st/blog/greenpass.html
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-] A 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
Once we peel this onion, we're left with the bytes that make up the
signed document. Highlighted blue, is the metadata (Key ID and
signature algorithm used), green is the signature, and yellow is the
main CBOR data structure. The non-ASCII part at the beginning is the
QR code's issuer, and expiry and generation dates as a 32 bit UNIX
timestamp, the rest of the values are just about readable as-is.
t@thi3nkpad ~ % zbarimg --raw greenpass.png|cut -b5-|tr -d '\n'|
base45 --decode|openssl zlib -d|xxd
00000000: d284 4da2 0448 d919 375f c1e7 b6b2 0126 ..M..H..7_.....&
00000010: a059 0133 a404 1a60 d345 6506 1a60 d0a2 .Y.3...`.Ee..`..
00000020: 6501 6241 5439 0103 a101 a461 7681 aa62 e.bAT9.....av..b
00000030: 646e 0162 6d61 6d4f 5247 2d31 3030 3033 dn.bmamORG-10003
00000040: 3032 3135 6276 706a 3131 3139 3334 3930 0215bvpj11193490
00000050: 3037 6264 746a 3230 3231 2d30 322d 3138 07bdtj2021-02-18
00000060: 6263 6f62 4154 6263 6978 3155 524e 3a55 bcobATbcix1URN:U
00000070: 5643 493a 3031 3a41 543a 3130 3830 3738 VCI:01:AT:108078
00000080: 3433 4639 3441 4545 3045 4535 3039 3346 43F94AEE0EE5093F
00000090: 4243 3235 3442 4438 3133 2342 626d 706c BC254BD813#Bbmpl
000000a0: 4555 2f31 2f32 302f 3135 3238 6269 7378 EU/1/20/1528bisx
000000b0: 1b4d 696e 6973 7472 7920 6f66 2048 6561 .Ministry of Hea
000000c0: 6c74 682c 2041 7573 7472 6961 6273 6402 lth, Austriabsd.
000000d0: 6274 6769 3834 3035 3339 3030 3663 6e61 btgi840539006cna
000000e0: 6da4 6366 6e74 754d 5553 5445 5246 5241 m.cfntuMUSTERFRA
000000f0: 553c 474f 4553 5349 4e47 4552 6266 6e75 U