diff --git a/qrcode-certificate/v0/certificate.png b/qrcode-certificate/v0/certificate.png new file mode 100644 index 0000000..5180720 Binary files /dev/null and b/qrcode-certificate/v0/certificate.png differ diff --git a/qrcode-certificate/v0/check_qrcode_certificate.py b/qrcode-certificate/v0/check_qrcode_certificate.py new file mode 100644 index 0000000..571b513 --- /dev/null +++ b/qrcode-certificate/v0/check_qrcode_certificate.py @@ -0,0 +1,24 @@ +import base64 +import binascii + +import nacl.signing + + +def base64url_decode(raw): + rem = len(raw) % 4 + if rem > 0: + raw += b'=' * (4 - rem) + return base64.urlsafe_b64decode(raw) + + +hex_verify_key = '79a441b73a99ead8c4446aa36c973dd23787d459122fe2169232a07a181e37a9' + +verify_key = nacl.signing.VerifyKey(binascii.unhexlify(hex_verify_key)) + +message = 'eyJ0eXBlIjogImNlcnRpZmljYXQtemZlIiwgImltbWF0cmljdWxhdGlvbiI6ICJBWi0xMjM0LUJFIiwgIm5vbSI6ICJKZWFuIE1hcmMgRHVwb25kIiwgImRhdGVfZW1pc3Npb24iOiAiMjAyMi0wNi0wNyJ9.Nno9aCyay5sxducJtpmuBDP8VBoRdwe4rfw3ohBP1bSBnmFJf17sXQdMDGDXt6eN6bzyfeI3mDrmpTnVDf81DQ' + +parts = message.encode().split(b'.') +payload = base64url_decode(parts[0]) +signature = base64url_decode(parts[1]) + +assert verify_key.verify(payload, signature) diff --git a/qrcode-certificate/v0/make_qrcode_certificate.py b/qrcode-certificate/v0/make_qrcode_certificate.py new file mode 100644 index 0000000..335a44d --- /dev/null +++ b/qrcode-certificate/v0/make_qrcode_certificate.py @@ -0,0 +1,49 @@ +import base64 +import binascii +import json + +import nacl.signing +import qrcode +import qrcode.constants +import qrcode.image.svg + + +def base64url_decode(raw): + rem = len(raw) % 4 + if rem > 0: + raw += b'=' * (4 - rem) + return base64.urlsafe_b64decode(raw) + + +def base64url_encode(raw): + return base64.urlsafe_b64encode(raw).rstrip(b'=') + + +key = nacl.signing.SigningKey(seed=b'1234' * 8) +print('Hex verify key:', binascii.hexlify(key.verify_key.encode()).decode()) +doc = { + 'type': 'certificat-zfe', + 'immatriculation': 'AZ-1234-BE', + 'nom': 'Jean Marc Dupond', + 'date_emission': '2022-06-07', +} + +payload = json.dumps(doc).encode() +signed = key.sign(payload) +certificate = b'%s.%s' % (base64url_encode(payload), base64url_encode(signed.signature)) + +# verify +b64_payload, b64_signature = certificate.split(b'.') +assert key.verify_key.verify(base64url_decode(b64_payload), base64url_decode(b64_signature)) + +print(f'Certificate({len(certificate)} bytes):', certificate) + +qr = qrcode.QRCode( + error_correction=qrcode.constants.ERROR_CORRECT_L, + # image_factory=qrcode.image.svg.SvgPathImage, +) +qr.add_data(certificate) +qr.make(fit=True) +img = qr.make_image(fill_color='black', back_color='white') +with open('certificate.png', 'wb') as fd: + img.save(fd) diff --git a/qrcode-certificate/v0/qrcode-reader/index.html b/qrcode-certificate/v0/qrcode-reader/index.html new file mode 100644 index 0000000..18069b1 --- /dev/null +++ b/qrcode-certificate/v0/qrcode-reader/index.html @@ -0,0 +1,89 @@ + + + + + + + + +
+ +
+ +

+            
+ + + + +