Coder Social home page Coder Social logo

sikerdebaard / coronacheck-tools Goto Github PK

View Code? Open in Web Editor NEW
38.0 7.0 9.0 69.06 MB

Unofficial tool to verify, encode and decode the domestic QR code from CoronaCheck.nl. Not affiliated with CoronaCheck.nl or Ministry of VWS.

License: MIT License

Python 88.48% Shell 1.37% Makefile 8.05% Go 2.09%
coronacheck scanner qr-code qrcode encoder decoder python3 validate validator

coronacheck-tools's Introduction

badge

coronacheck-tools

This is an unofficial tool that is in no way affiliated with CoronaCheck.nl or the Ministry of VWS. You have been warned!

coronacheck-tools is a python package and cli tool that allows you to validate, convert and dump the contents of the domestic coronacheck qr code generated at https://coronacheck.nl either through the app or the website. This tool is useful to get some insight into the data stored in these QR Codes, to fuzz the fields or to create your own QR validator.

Installation

Python

# Install the package through pip
# This package requires python 3.6 or higher
# Depending on your Operating System you might need to install some extra dependencies.
# E.g. ubuntu linux: apt install ffmpeg libsm6 libxext6 zbar-tools
#      OSX: brew install zbar
#      Windows: choco install zbar
> pip install coronacheck-tools

# Example: dumping QR code data to JSON
> coronacheck-tools dump json /path/to/qrcode.jpg /path/to/output/directory

# Example: validate QR Code
> coronacheck-tools verify qr /path/to/qrcode.jpg

# Example: convert QR to ASN1 DER
> coronacheck-tools convert qr /path/to/qrcode.jpg asn1 /path/to/output/directory

# Example: convert ASN1 DER to QR
> coronacheck-tools convert asn1 /path/to/asn1.der qr /path/to/output/directory

Docker

# Running the tool through docker is quite easy.
# Just docker run sikerdebaard/coronacheck-tools:latest
# Optional: add --user `id -u` to change the uid/group of output files to the current user

# Example: dumping QR code data to JSON
> docker run --rm -v /path/to/your/data:/data sikerdebaard/coronacheck-tools:latest dump json /data/qrcode.jpg /data

# Example: validate QR Code
> docker run --rm -v /path/to/your/data:/data sikerdebaard/coronacheck-tools:latest verify qr /data/qrcode.jpg

# Example: convert QR to ASN1 DER
> docker run --rm -v /path/to/your/data:/data sikerdebaard/coronacheck-tools:latest convert qr /data/qrcode.jpg asn1 /data

# Example: convert ASN1 DER to QR
> docker run --rm -v /path/to/your/data:/data sikerdebaard/coronacheck-tools:latest convert asn1 /data/asn1.der qr /data

Usage

The tools main commands are as follows: verify, dump, convert, denylist and asn1spec.

verify

This command is used for verifying a QR code. It supports a QR image, RAW, ASN1 DER and JSON as input for verification. This tool uses a thin wrapper around the official mobilecore verifier as used by the CoronaCheck.nl app.

> coronacheck-tools verify --help

This is an unofficial tool that is in no way affiliated with CoronaCheck.nl or the Ministry of VWS
USAGE
  coronacheck-tools verify <input-format> <input>

ARGUMENTS
  <input-format>         Input format. QR, RAW, ASN1, JSON.
  <input>                Input file.

GLOBAL OPTIONS
  -h (--help)            Display this help message
  -q (--quiet)           Do not output any message
  -v (--verbose)         Increase the verbosity of messages: "-v" for normal output, "-vv" for more verbose output and "-vvv" for debug
  -V (--version)         Display this application version
  --ansi                 Force ANSI output
  --no-ansi              Disable ANSI output
  -n (--no-interaction)  Do not ask any interactive question

dump

Dump is for converting and image with a QR code to RAW, ASN1 DER or JSON.

> coronacheck-tools dump --help

This is an unofficial tool that is in no way affiliated with CoronaCheck.nl or the Ministry of VWS
USAGE
  coronacheck-tools dump <format> <image> <output>

ARGUMENTS
  <format>               Output format. RAW, ASN1, JSON.
  <image>                Path to an image file with one or more QR codes.
  <output>               Output directory. Will overwrite existing files.

GLOBAL OPTIONS
  -h (--help)            Display this help message
  -q (--quiet)           Do not output any message
  -v (--verbose)         Increase the verbosity of messages: "-v" for normal
                         output, "-vv" for more verbose output and "-vvv" for
                         debug
  -V (--version)         Display this application version
  --ansi                 Force ANSI output
  --no-ansi              Disable ANSI output
  -n (--no-interaction)  Do not ask any interactive question

convert

The convert command helps in converting one format into another. Supported formats are QR image, RAW, ASN1 DER and JSON. The tools can upconvert or downconvert. E.g. QR -> JSON or JSON -> QR, but it can also be used for cloning QR -> QR. This is usefull for convert a QR in a fuzzy image to a crisp clean QR.

> coronacheck-tools convert --help

This is an unofficial tool that is in no way affiliated with CoronaCheck.nl or the Ministry of VWS
USAGE
  coronacheck-tools convert <input-format> <input> <output-format> <output>

ARGUMENTS
  <input-format>         Input format. QR, RAW, ASN1, JSON.
  <input>                Input file.
  <output-format>        Output format. QR, RAW, ASN1, JSON.
  <output>               Output directory. Existing files will be overwritten without warning.

GLOBAL OPTIONS
  -h (--help)            Display this help message
  -q (--quiet)           Do not output any message
  -v (--verbose)         Increase the verbosity of messages: "-v" for normal output, "-vv" for more verbose output and "-vvv" for debug
  -V (--version)         Display this application version
  --ansi                 Force ANSI output
  --no-ansi              Disable ANSI output
  -n (--no-interaction)  Do not ask any interactive question

denylist

This tool lists all entries on the deny list and optionally checks if a given QR code is on the denylist if such a parameter is given.

> coronacheck-tools denylist --help
This is an unofficial tool that is in no way affiliated with CoronaCheck.nl or the Ministry of VWS
USAGE
  coronacheck-tools denylist [<input-format>] [<input>]

ARGUMENTS
  <input-format>         Optional input format (must be combined with <input>)
  <input>                Optional input QR code data (must be combined with <input-format>)

GLOBAL OPTIONS
  -h (--help)            Display this help message
  -q (--quiet)           Do not output any message
  -v (--verbose)         Increase the verbosity of messages: "-v" for normal output, "-vv" for more verbose output and "-vvv" for debug
  -V (--version)         Display this application version
  --ansi                 Force ANSI output
  --no-ansi              Disable ANSI output
  -n (--no-interaction)  Do not ask any interactive question

asn1spec

This tool shows the ASN1 specification as used for deserializing the QR code data.

> coronacheck-tools asn1spec --help

This is an unofficial tool that is in no way affiliated with CoronaCheck.nl or the Ministry of VWS
USAGE
  coronacheck-tools asn1spec [<version>]

ARGUMENTS
  <version>              Currently supported versions: 2 "2"

GLOBAL OPTIONS
  -h (--help)            Display this help message
  -q (--quiet)           Do not output any message
  -v (--verbose)         Increase the verbosity of messages: "-v" for normal output, "-vv" for more verbose output and "-vvv" for debug
  -V (--version)         Display this application version
  --ansi                 Force ANSI output
  --no-ansi              Disable ANSI output
  -n (--no-interaction)  Do not ask any interactive question

Python API

This package requires python 3.6 or higher

The python library allows for a little bit more control over how the qr-code is decoded. Here's an example script on how to dump a qr-code to ASN.1 and then read the ASN.1 and convert it to a dict. Finally the script wil re-encode the whole thing back to a QR code.

from coronacheck_tools import decode_qr, decode_raw, decode_asn1_der, decode_to_dict, encode_dict, raw_to_qr, validate_raw

# An image can contain multiple QR codes. As such, this function always returns an array with decoded data.
# Format can be the following:
#  RAW = Just grab the raw data from the QR code(s) in the image
#  ASN1_DER = Decoded QR Code data. The raw data is confiks and then base45 decoded. This results in a ASN.1 DER blob.
#  ASN1 = Uses the ASN.1 specification to decode the ASN.1 DER data. This is then represented as a dict. Some of the fields in this data
#         are still encoded. Mainly the aDisclosed records still need some decoding. The data is almost usable at this point.
#  DICT = Decode everything, even the records within aDisclosed, and output a dict.


# Let's first convert the qr-code to an ASN1 DER.
asn1s = decode_qr('test/testdata/qrtest.png', format='asn1_der')

# Store the first QR code's ASN.1 DER to disk
with open('/tmp/asn1der.asn', 'wb') as fh:
    fh.write(asn1s[0])


# This ASN1 blob can be read by tools like openssl
# E.g.: openssl asn1parse -in /tmp/test/asn1blob.asn -inform DER


# Let's read the ASN.1 DER data from disk
with open('/tmp/asn1der.asn', 'rb') as fh:
    asn1_der = fh.read()

# Since it's an ASN.1 DER we have to use decode_asn1_der to deserialize it.
# Like all of these functions it allows for a desired format parameter.
# Data can always be converted to the next step in the pipeline but
# never backwards. It always happens in this order:
# RAW -> ASN1_DER -> ASN1 -> DICT
#
# Lets convert the blob to a DICT

data = decode_asn1_der(asn1_der, format='dict')


# Now lets re-encode the dict back to RAW and dump it as a QR code
# As it's a dict, we have to use encode_dict
rawdata = encode_dict(data, 'RAW')


# Now convert RAW to a QR code image
raw_to_qr('/tmp/qrcode.png', rawdata)


# Finally let's validate the QR Code!
validity = validate_raw(rawdata)

Example scripts

You can find some example python scripts here. E.g. how to fuzz some of the QR code fields or how to read (and validate) the QR from a webcam.

License and academic use

The program is licensed under the MIT License.

For academic use, use a presistent copy from DOI

Please cite:

Phil, T. (2021). Sikerdebaard/coronacheck-tools: v5 (v5) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.5711213

coronacheck-tools's People

Contributors

dependabot[bot] avatar sikerdebaard avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

coronacheck-tools's Issues

Understand how the validation tool works.

Greetings,
I am trying to develop a tool similar to yours, but in Java. The problem is that I don't understand how you perform the verification process. I have done many tests with your tool and I see that it works correctly (even offline, necessary part for my project), but I do not understand the verification process.... I have been able to verify that if any change is made to any of the variables in the generated json ("disclosureTimeSeconds", "c", "a", "eResponse", "vResponse", "aResponse" or "aDisclosed"), the program detects that it is invalid code, but I don't understand the process it follows to reach that conclusion and I need to replicate it in Java.
If you could guide me about the path it follows to perform the checks I would be very grateful.

Regards.

Could not verify domestic QR code

Hi,

Ik krijg de error: Code is invalid Could not verify domestic QR code: Could not verify v2 proof: Invalid proof.

Is dit iets wat ik zelf verkeerd doe of is er ondertussen iets gewijzigd waardoor de code niet helemaal meer accuraat is?

Help requested on validating the QR code!

The encryption part of this qr code seems to use IRMA. It looks like the mobile Android and iOS app use a library called Gabi for this.

This struct seems to be populated based on records from the deserialized ASN.1 data. This data is then somehow magically mixed in this function by Gabi which then somehow proves that the data is valid or not.

I'm not sure how to tackle this in Python. This stuff seems pretty bleeding edge and I'm not sure if this can be implemented with encryption primitives from e.g. libs like cryptography or openssl.

TODO: migrate cv2 -> Pillow

cv2 is a bit heavy for the limited image processing tasks done by this library. Migrating cv2 to Pillow would make this library a lot faster to install on systems where cv2 wheels aren't necessarily available. E.g. some linux arm systems.

How to analyse output

Dear Sikerdebaard,

We've been implementing the code and get data. Nice!

Question i have is how to analyse the output.

Fields validFrom and validForHours seem to be incomprehensible to us. How should we analyse the contents of these fields?

What determines if a person is "green" or "red"?

Thanks for asssisting!

Mark

ValueError invalid literal for int() with base 10: ''

ValueError

invalid literal for int() with base 10: ''

  at c:\users\aziz\appdata\local\programs\python\python39\lib\site-packages\coronacheck_tools\verification\mobilecore.py:59 in _ensureconfig
      55│     timestamp_file = confdir / 'timestamp'
      56│
      57│     if timestamp_file.exists():
      58│         with open(timestamp_file, 'r') as fh:
    → 59│             timestamp = datetime.utcfromtimestamp(int(fh.read()))
      60│
      61│         now = datetime.utcnow()
      62│         if timestamp >= now - timedelta(hours=24):
      63│             # no need to refresh the config

Question about c, a and response fields

Hey there,

Thanks for your cool repo about seeing what's inside the QR code! Really interesting stuff.
I was wondering what the c, a, eResponse, vResponse and aResponse fields mean. They seem to be still encoded? What is in this fields? They seem to change with every QR code too. Is there a page where I can find more information about this?

Thanks for any help :)

birthMonth decoding issue

There seems to be a minor decoding issue with the current app (from RAW and QR): "birthMonth": "\u0000"

Full raw or QR code can be supplied in private.

Can't verify international code

it seems to run into this problem


  'NoneType' object is not subscriptable

  at /usr/local/lib/python3.9/site-packages/coronacheck_tools/verification/mobilecore.py:37 in validate
       33│         return False, result['Error']
       34│ 
       35│     result = result['Details']
       36│ 
    →  37│     if result['credentialVersion'] == '1':
       38│         # if this field is set to 1 it is actually a european EHC
       39│         result['isEHC'] = True
       40│         result['isDHC'] = False
       41│     else:```

Upgrade issue on windows: (Python 3.10) numpy==1.19.3

Running the upgrade command on windows 10:
pip3 install coronacheck-tools --upgrade

Upgrade failes with the following error:

Collecting numpy==1.19.3
        Using cached numpy-1.19.3.zip (7.3 MB)
        Installing build dependencies: started
        Installing build dependencies: finished with status 'done'
        Getting requirements to build wheel: started
        Getting requirements to build wheel: finished with status 'done'
        Preparing metadata (pyproject.toml): started
        Preparing metadata (pyproject.toml): finished with status 'error'
        error: subprocess-exited-with-error

        Preparing metadata (pyproject.toml) did not run successfully.
        exit code: 1

        [267 lines of output]
        setup.py:67: RuntimeWarning: NumPy 1.19.3 may not yet support Python 3.10.
          warnings.warn(
        Running from numpy source directory.
        setup.py:480: UserWarning: Unrecognized setuptools command, proceeding with generating Cython sources and expanding templates

× pip subprocess to install build dependencies did not run successfully.
│ exit code: 1
╰─> [307 lines of output]
Ignoring numpy: markers 'python_version == "3.6" and platform_machine != "aarch64" and platform_machine != "arm64"' don't match your environment
Ignoring numpy: markers 'python_version >= "3.6" and sys_platform == "linux" and platform_machine == "aarch64"' don't match your environment
Ignoring numpy: markers 'python_version >= "3.6" and sys_platform == "darwin" and platform_machine == "arm64"' don't match your environment
Ignoring numpy: markers 'python_version == "3.7" and platform_machine != "aarch64" and platform_machine != "arm64"' don't match your environment
Ignoring numpy: markers 'python_version == "3.8" and platform_machine != "aarch64" and platform_machine != "arm64"' don't match your environment

Missing dependencies

It seems like the package is dependent on:
libGL.so.1 & zbar which, in my case, could be solved by:

sudo apt-get install libgl1-mesa-glx zbar-tools

Can't run it in WSL, Windows or Docker

I am unable to run the project is all available systems I have. I guess I am doing something very simple wrong, but I don't know what. Is there somewhere a baseguide to install and run python in WSL or Windows?

Thanks in advance!

Discussion: REST Server or SaaS API for commercial use?

I'm thinking of developing a REST API around this library. This could then be utilized to run the official MinVWS mobilecore verifier through this library on devices like ticket terminals. For offline requirements, e.g. festivals, this library + configs could be preloaded and refreshed once every x-days. For online devices a SaaS API could be utilized with a pay-as-you-go type subscription.

Would there be interest in such a thing? What requirements would you have for this?

For example if the library would be able to read the MRZ and/or NFC of an identity card / passport and automatically verify this with the information on the QR code would that be enough or would it still be necessary for a person to verify the ID proof? Of course there would need to be a fallback for unreadable ID proof but I think this could save some time as you would probably need less staff.

Would it be interesting to check if certain QR codes have been used more than once in your venue? There's a unique token in the domestic QR that could be utilized for this. This won't work if a person generated multiple QR codes but at the very least you could utilize it to see if a specific QR code has been scanned a suspicious number of times.

Are there analytics that might be useful? E.g. how many paper or app QR codes have been scanned or how many domestic or EHC codes? Is it allowed to gather such analytics?

Updates to denylist?

Hey,

As there's now 23 keys that have been added to deny-list, I would like to see a update to this.
Any idea how we could streamline adding newly denied QRs?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.