Created
September 16, 2021 09:19
-
-
Save dbolkensteyn/858086a9db9365715bab582a2adc0d0c to your computer and use it in GitHub Desktop.
Generates an (invalid) COVID-19 EU certificate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import base45 | |
import cbor2 | |
import zlib | |
from binascii import unhexlify | |
from cose.messages import Sign1Message | |
from cose.keys import CoseKey | |
# Specifications: https://ec.europa.eu/health/sites/default/files/ehealth/docs/covid-certificate_json_specification_en.pdf | |
payload = { | |
-260: { | |
1: { | |
'ver': '1.3.0', | |
'nam': { | |
'fn': 'LE BRON', | |
'gn': 'JAMES', | |
'fnt': 'LE<BRON', # Normalized, replace special chars by '<' | |
'gnt': 'JAMES', # Normalized, replace special chars by '<' | |
}, | |
'dob': '1984-12-30', # Date of birth | |
'v': [ # 'v' stands for vaccination | |
{ | |
'is': 'Bundesamt für Gesundheit (BAG)', # Authority issuing this certificate | |
'ci': 'urn:uvci:01:CH:CXDOS8PHU3BTI0HR368FKUMK', # Unique certificate ID assigned by the authority above | |
'co': 'Switzerland', # Country of vaccination | |
'dn': 2, # Number of doses injected | |
'dt': '2021-08-01', # Date of last injection | |
'sd': 2, # Number of doses required for full vaccination | |
'ma': 'ORG-100030215', # Manufacturer: Biontech Manufacturing GmbH | |
'mp': 'EU/1/20/1528', # Product: Comirnaty | |
'tg': '840539006', # Target disease: COVID-19 | |
'vp': '1119349007', # Vaccine type: SARS-CoV-2 mRNA vaccine | |
}, | |
], | |
} | |
} | |
} | |
# Sign message with a random key and algorithm (not known by verifying devices, hence invalid) | |
# https://pycose.readthedocs.io/en/latest/index.html | |
msg = Sign1Message(phdr = {"ALG": 'EDDSA'}, payload = cbor2.dumps(payload)) | |
msg.key = CoseKey.from_dict({ | |
"KTY": "OKP", | |
"CURVE": "ED25519", | |
"D": unhexlify(b'9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60'), # Private key | |
"X": unhexlify(b'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a'), # Public key | |
}) | |
# Encoding | |
data = msg.encode() | |
data = zlib.compress(data, 9) | |
data = base45.b45encode(data) | |
data = "HC1:" + data.decode("ascii") | |
print(data) | |
# Prints out: | |
# HC1:NCFOXN*TS0BIP$FQP4EVPAN9I6T5XH4PIQJAZGA+1V2:U:PI/E2$4JY/KB:KVCNV375RV7Y4 CTEKFGVV0Z06ALT$I*U0:68TNP8EFY9AP$I/XK$M80I1PZB8L45QC:%OD3PVD98-OKSUG-K0C5Y/OCINAE1M8HVO2LFNAZ2PT0SHA5M9DT69T3ZY6WLIFO5YO9OUUMK9WLIK*L5R1$XJ/ L7L4N-V2V5 R7S+H G8DU1UMG9.PX+R.N8L/N:PIAVM:UPKP9QJA.IEAYUIMI4UUIMI.J9WVHWVH+ZE+R5AT1FTIPPA5NITK292W7*RBT1ON1EYH6I6IE9WT0K3M9UVZSVV*001HW%85B9-NT0 2$$0X4PCY0+-CVYCDEBD0HX2JR$4O1K%XGNZA45SQVMF13A/C1$9I38F0P9L41MDB2RJ5HTC6%CVE-M6+NHXL6LJ% 7GA3:9MYC9C26GUF8AP6-F838P4JEGW%44USCB6RXA1GR9- F9VE | |
# Store data in QR code, e.g. https://www.the-qrcode-generator.com |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment