I Am Vaccine Passports (And So Can You!)

BC has rolled out digital "vaccine passports" in the form of a QR code, and Ontario has committed to doing the same. If you're like me, you're curious how these codes work, what information is stored in them, and whether you can generate them on your own. Spoiler alert: you can (sort of)!

A screenshot of the smart health card verification app reading "Partially Verified: Valid SMART health card, issuer not recognized."  The accompanying vaccination record is clearly fake, listing my birth year as 1970 and my first shot of Moderna as having been administered by "some guy in an alley".

SMART Health Cards

The emerging standard for proof-of-vaccination QR codes (used in BC, among many other jurisdictions) is the SMART Health Card framework. The approach is pretty much what anyone with some mild knowledge of cryptography would expect:

  • The generated QR code contains all relevant information (patient name, DOB, and information about where & when each dose was administered), so no internet connection is needed.
  • All information is cryptographically signed using a private key belonging to whoever issued the code. For instance, if the card claims to have been issued by the government of BC then it should be signed using a secret private key controlled only by the government of BC. It should be essentially impossible (with present technology) to fake this digital signature if you don't have access to the private key.
  • When scanning the QR code, the public key of the issuer can be used to verify the digital signature, confirming that the card was issued by the holder of the corresponding private key.
  • In the case of a custom scanner app, like BC's official app, the public keys of all trusted issuers can be stored in the app itself, so no internet connection is necessary.
  • For a general-purpose app, like the one released by The Commons Project, the public key can be retrieved from the internet. So if the QR code claims to have been signed by ontario.ca/vaccination the app retrieves the public key from that url, and if the signature is valid then you at least know that the QR code must have been issued by whoever controls that url. But in this case it's up to the user to decide whether this entity is trustworthy.

For more on public key cryptography, and the specific method used by SMART health cards (elliptic curve cryptography), check out this introduction.

Issuing Your Own SMART Health Cards

It's pretty easy to issue your own SMART health card vaccination records. The standard is public and well-documented, and you can find my script for generating the QR codes here.

I was able to easily generate QR codes like the following:

A valid SMART health card QR code with a slightly visible purple smiley face imposed on top.

If you try scanning this using the Commons Project's verifier app it'll appear as "Partially Verified" with an "unknown issuer" at https://noctes.mathematicae.ca/vaccination. However, BC's official verifier app will not recognize it because I am obviously not trusted by the government of BC.

Possible Attacks

If you wanted to use a fake vaccination record to flout proof-of-vaccination laws somewhere, how would you do it?

Assuming there's an official government-issued app with a fixed list of trusted issuers (like in BC), you basically only have the following options:

  • Obtain access to the private key of a valid issuer (presumably by hacking a government computer or possibly bribing a government employee).
  • Trick your target (or the general public) into downloading a fake verifier app that you control.
  • Be the CIA/FBI/NSA (maybe). The elliptic curve required by the SMART standard is the NIST P-256 curve, which is distrusted by a lot of security experts. It's suggested by the US National Institute of Standards and Technology, and thus could be compromised by US intelligence. And the process used to generate the curve coefficients involved hashing an unexplained choice of random seed, which leaves open the possibility that this particular seed was chosen because the resulting curve has some property (known to e.g. the CIA) that makes this curve easy to exploit. For this and other reasons why this curve might be bad, see here.

But what if the government gets lazy and decides to use the existing Commons Project app or another general-purpose verifier app?

The Commons Project app checks issuers against lists recognized by the CommonTrust Network. I have no idea how the entities on these lists are verified; it might be possible to somehow fake your way in with a plausible-looking url/website and some social engineering skills. This could allow your QR codes to appear as fully verified in the app.

Moreover, it's worth noting that valid cards issued by BC are currently not recognized by this app, and I assume the same is true of plenty of other legitimate government entities. So in a setting where vaccinations from other jurisdictions are supposed to be accepted, the fact that you're not recognized by the app might not be a big obstacle to convincing a typical bouncer, receptionist, etc. that your codes are valid; they probably come across legitimate but only "partially verified" codes on a semi-regular basis. So maybe all you need to do is obtain a plausible lookalike url for some random county in Idaho.

Finally, since the Commons Project app fetches public keys from the internet, other methods of attack include hacking the website of a trusted issuer, or performing a man-in-the-middle attack when the app is fetching the key (which is still basically impossible since https is required by the standard, but at least this way you only have to break RSA and not ECC).

What about Ontario?

So far, Ontario has not released much information about their planned QR code approach. I've seen articles stating that they're considering a system "similar to BC", which suggests the SMART standard, but I haven't seen anything explicitly mentioning the standard.

What I have seen is references to a "made-in-Ontario" app being developed "in-house."1 In the best-case scenario, this just means that they're going to use the SMART standard but release an official app, like BC did. That would be good (allowing coordination with other provinces and avoiding many of the attacks mentioned above).

But in the worst-case scenario an "in-house" app could mean a totally novel approach that's not compatible with any other province or country, with a more invasive, internet-dependent, or insecure protocol. I guess we'll just have to wait and see which we get.


  1. See e.g. here