Inside India’s vaccine certificate

Aniruddha Achar
4 min readJun 3, 2021

A few days back I was vaccinated. It was not the most pleasant experience for me. I spiked a fever that night; that zapped the energy out of me the next day. I was curious to see if I had my vaccination certificate. I logging on to the Cowin portal and downloaded the certificate. Cowin is the vaccination registration and tracking portal that is used in India. Here is a template of the certificate.

Covid vaccination sample certificate

I was curious to know what is the QR code and what data is encoded there. I was expecting the name, age, ID, and other details to be encoded in plain text. Launching a QR code launcher app on my phone I tried to scan the QR code. I was surprised when the app didn’t recognize the QRcode. Well, that was odd and I decided to explore further. The QR code appears to be more complex than the simple QR codes that I had seen. I decided to use a better QR code scanner on the web to see if it recognizes something. Well to my surprise it did. But to my horror, the data looked to be non Unicode or ANSII in nature. At least the web QRcode scanner decoded something. This was better than the phone’s scanner. Now I know it is not a simple string, this is more interesting now. The next step would be to look at the binary representation of the decoded QR code to understand what it may represent. I was not happy that I had to put a lot more time into this than what I was ready for. That is when I saw the text at the bottom of the QR code. (The image above is of the old certificate. The text is not present there.) It directed me to verify the certificate on https://verify.cowin.gov.in/. Cool, I can use this to decode the certificate. Fired that up on my phone, aligned the camera with the QR code, and there it was; the certificate details. I was happy that I can decode this QR Code now. The question, what does the QR code really encode.

After a few hours of doing things that are well… more important, I opened https://verify.cowin.gov.in/ on my desktop and scrolled down and to my surprise the certification verification app is open source. This is cool, I can now walk through the code to see what the QR code encodes. The repository can be found here https://github.com/egovernments/DIVOC/tree/india/verification.

This was late in the night and I was too tired to deploy the application on any of my machines. I am not fluent in JavaScript and the development environment. Setting one up, breaking into the code would be a hassle so I decided to brute force it and walk through the code by hand.

The code layout was good and walking through the code was not that difficult. The meat of code that does the decoding is here

The developers of the application are using zbar.wasm library to decode the QR code. Reading the documentation for zbar call to scanImageData returns an image of symbols. Usually, the first element of the array is the bar code type. The second element is the data in the barcode. Calling the decode method on the symbol decodes the code. A good read to understand how QR Codes really work https://www.qr-code-generator.com/qr-code-marketing/qr-codes-basics/.

Now that I knew how the QR Code is being decoded, the next step for me was to understand what was being decoded. Following code flow, I landed here

Aha! There it is. The content of the QR Code is a zip file. This is quite interesting. Looking at the documentation for JSZip, I found that the developers are here decompressing the decoded QRcode. The zip file has a file inside it called “certificate.json”. This is neat.

Now that I know there was a JSON file that we are looking at. The next action plan was to get the content of the file. Here is some quick and dirty code to get the JSON data out.

The test image above is the image of the QR Code. There is a lot of additional data that the JSON file has that is used to validate the data. I found that validation is done using something called linked data signature. Well… that is something I need to read up on to understand.

This is what a sample JSON output would look like

Just a thought. When you print this certificate onto paper, you will have a digital file on a physical file.

Disclaimer: I am not associated with the developers of the code. All the research done here is using the open-source code repository. Use the code snippet at your own risk.

--

--