-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
164 lines (153 loc) · 9.22 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<html>
<head>
<title>shc-decode</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/jpg" href="favicon.ico"/>
<link rel="stylesheet" type="text/css" href="index.css" />
<link rel="stylesheet" type="text/css" href="water.css" />
<script type="text/javascript" src="pako_inflate.min.js"></script>
</head>
<body>
<section>
<h1>shc-decode</h1>
<p>Decode your Ontario COVID-19 Vaccination QR code (<b>S</b>mart <b>H</b>ealth <b>C</b>ard).</p>
</section>
<section>
<h2>Details</h2>
<details>
<summary>
<b>⌛ Limitations:</b> Does this site verify QR codes? No. Click to learn more.
</summary>
<p>
This site does not verify the authenticity of vaccination QR codes.
<br/>
Please use the <a href="https://covid-19.ontario.ca/verify">Verify Ontario mobile app</a>.
<br/>
<br/>
This tool is also focused on Ontario vaccination codes and may not work on SHC codes from
other regions.
</p>
</details>
<details>
<summary>
<b>🔐 Privacy:</b> Is this site extracting data? No. Click to learn more.
</summary>
<p>
This site does not extract any data. It does not send data to any external service.
All data is processed on your local web browser. This site does not use cookies or
local storage of your browser to save state.
</p>
<p>
The decoded Ontario vaccine QR code contains your legal name, date of birth, and COVID
vaccination details (type of shots and dates received).
</p>
<p>
If you'd like to be extra safe you can:
<ul>
<li><a href="https://github.com/OliverCardoza/shc-decode">Audit the code</a></li>
<li><a href="https://stackoverflow.com/questions/16806343/chrome-disable-internet-connection-or-work-offline">Disable Chrome network</a> before using</li>
<li><a href="https://support.google.com/chrome/answer/7343019">Download the page offline and use it with device in airplane mode</a></li>
</ul>
</p>
</details>
<details>
<summary>
<b>❓ Motivation:</b> Why did you do this? Click if you're curious.
</summary>
<p>
I recently started working at <a href="https://verily.com/">Verily</a>, a sister
company to Google, which focuses on healthcare and life sciences. I've been learning
about the tech used to generate the COVID QR codes including the
<a href="https://hl7.org/FHIR/">FHIR</a> data format, and the
<a href="https://smarthealthit.org/">SMART</a> app framework. When I received my
vaccination QR code it seemed like a perfect opportunity to dive in deeper.
</p>
<p>
At first I found a few Python decoding examples (
<a href="https://github.com/tahnok/ont_shc_decode/">[1]</a>,
<a href="https://marcan2020.medium.com/reversing-smart-health-cards-e765157fae9">[2]</a>).
but I didn't want to go through the hassle of setting up a Python workspace.
Then I found
<a href="https://fproulx.github.io/shc-covid19-decoder/">shc-covid19-decoder</a>
but it didn't work for me. I couldn't stop thinking about it so I decided to make my own.
In the end, I found it a consuming learning experience as I dove into the quirks of JWTs,
base64 encoding, and zlib compression used by SMART Health Cards.
</p>
<p>
If this kind of stuff gets you psyched, then you may be interested
in a job at Verily! We're currently hiring in Verily Canada with open roles in software,
data science, UX, and more. Please apply here at
<a href="https://verily.com/careers/?gh_src=a1b46b221us&locations=Kitchener-Waterloo%2C+ON">Verily Waterloo Jobs</a>
or shoot me a message on <a href="https://www.linkedin.com/in/olivercardoza/">LinkedIn</a>.
</p>
</details>
<details open>
<summary>
<b>🆘 Instructions:</b>
</summary>
<p>Follow the steps below to decode your QR code.</p>
<ol>
<li><b>Get your QR code:</b> <a href="https://covid19.ontariohealth.ca/">Ontario COVID-19 vaccination portal</a></li>
<li><b>Scan your QR code:</b> I screenshotted the PDF and used <a href="https://lens.google/#!#download">Google Lens</a> to scan it.</li>
<li><b>Copy the data:</b> The data should start with <code>shc:/</code> followed by numbers.</li>
<li><b>Enter it:</b> Paste it in to the input field on this site and click submit</li>
</ol>
</details>
</section>
<section>
<h2>Input</h2>
<input id="shc" type="text" placeholder="shc:/..." />
<input id="submit" type="submit" value="Submit" />
</section>
<section>
<h2>Output</h2>
<details>
<summary><b>Intermediary data</b></summary>
<p>SHC</p>
<code id="debug_shc" class="debug"></code>
<br/>
<p>JWT</p>
<code id="debug_jwt" class="debug"></code>
<br/>
<p>JWT Header</p>
<pre><code id="debug_jwt_header" class="debug"></code></pre>
<br/>
<p>JWT Payload - Encoded</p>
<code id="debug_jwt_payload_encoded" class="debug"></code>
<br/>
<p>JWT Payload - Decoded (Uint8Array)</p>
<code id="debug_jwt_payload_decoded" class="debug"></code>
</details>
<p>Payload</p>
<pre><code id="output">Enter an input and press enter to process...</code></pre>
</section>
<footer>
<a href="https://olivercardoza.com" class="footer-link">
<span class="icon">
<img src="favicon.ico" />
</span>
<span>olivercardoza.com</span>
</a>
<a href="https://twitter.com/OliverCardoza" class="footer-link">
<span class="icon">
<svg viewBox="0 0 16 16"><path fill="#828282" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809 c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"></path></svg>
</span>
<span>OliverCardoza</span>
</a>
<a href="https://github.com/OliverCardoza" class="footer-link">
<span class="icon">
<svg viewBox="0 0 16 16" height="16px"><path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"></path></svg>
</span>
<span>OliverCardoza</span>
</a>
</footer>
<a href="https://github.com/OliverCardoza/shc-decode" class="github-corner" aria-label="View source on GitHub">
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
</svg>
</a>
<script type="text/javascript" src="index.js"></script>
</body>
</html>