The Mighty Code That Saved Lives: Meet The QR Code

And my dream for the NHS

Can you determine the message?

The Mighty Code That Saved Lives: Meet The QR Code

And my dream for the NHS

Disclaimer: As a cybersecurity professional, I must start by saying that there are risks in scanning QR codes, and only do it, if you trust the person hosting the code, and check before following on to other content. Bad people can trick you into hiding their Web pages with a code — so watch out! For this blog post, you can scan the QR codes — I promise there is nothing hidden in them.

Introduction

Recently, I went to register for a GP and was handed a piece of paper and told to find a pen and write down all my details. In virtually every interaction with the NHS, I have had to do this, and perhaps, one day, I will have all my medical details stored on a digital wallet on my phone, and where the GP just scans them in. Once, I filled in it, it then went into a black hole — and where I hoped that a human would eventually make sense of my scribbles. In our new electronic work, to still rely on paper, pen and human interaction just feels strange. Overall, in places, it feels like there are still parts of our lives that are stuck in the 20th Century.

This all took me back to the time I worked with Prof Christoph Thummler on a grant which looked at using RFID and QR codes for medical equipment. We aimed to correctly identify medical equipment — and even patients — using a simple tag. Where did it get to? Well, we spun out a company named Symphonic — and which eventually got out of health care as it was just too difficult a sector to make any advances. But they found a market elsewhere. And you will be happy to know that Ping ID bought them out in 2020. And for Christoph? He’s now in Leipzig, and we are back working with him on 6G and homomorphic encryption in health care.

And, so, in the time of COVID-19, there was a little image that often meant the difference between travelling and not — the mighty QR code. With this, we created the concept of having a digitally signed health passport.

The Vaccine Password and the magic of the private key

To give you an understanding of how these passports are created, each trusted authority in each country will have a set of private and public keys (they should use more than one in case they have to revoke some of them). A single leak of the signing key pair would cause major problems, and would mean that all of the passports signed within that country would be revoked.

The vaccine status passport is signed by the private key and proven with the associated public key. This digital signature on the passport proves both its contents and its validity (or trustworthiness of the passport). When the passport is checked, it is then checked against a set of trusted public keys. These public keys can be stored centrally by each country or by the EU Commission. At a border check, the Validator App will have access to all of the trusted public keys.

When a private key has been found to have been leaked, the associated public key will be marked as untrusted and will be revoked. Anyone with a passport signed with this private key will then be marked as being invalid. A major compromise of these private keys would thus bring the whole infrastructure down and allow fake passports to be trusted. Many trusted passports would then be untrusted and cause difficulties for travellers. In terms of signatures, the passports normally use EdDSA, and which is fairly free of the weaknesses associated with ECDSA.

An overview of the processing is defined in [1] as [here]:

First we start with the basic data for the vaccine status report [here]:

{
"1": "GB",
"4": 1992212161,
"6": 1425632973,
"-260": {
"1": {
"v": [
{
"ci": "URN:UVCI:01:GB:D23AD1B216A11133B272BEA32C426AC0#D",
"co": "GB",
"dn": 1,
"dt": "2021-01-14",
"is": "NHS Anywhere",
"ma": "ORG-110302699",
"mp": "EU/1/21/1529",
"sd": 2,
"tg": "341534114",
"vp": "3339315014"
}
],
"dob": "1977-01-10",
"nam": {
"fn": "SMITH",
"gn": "FRED SMITH",
"fnt": "SMITH",
"gnt": "FRED SMITH"
},
"ver": "1.3.0"
}
}

This contains the date of birth of the person, their name, and the details of their vaccination. To then encode this into the QR, we create a signed object. In this following case, this is an EdDSA signature signed by a private key (such as from the NHS). The library used is COSE [here]:

message='{"1": "GB","4": 1772210913,"6": 1830374921,"-260": 
{ "1": {"v": [ {\"ci": \"URN:UVCI:01:GB:D36AF2C745B94400A176CF3E3B526BA#F",
"co": "GB","dn": 1,"dt": "2021-04-11","is": "NHS","ma": "ORG-100331689",
"mp": "EU/1/21/1529","sd": 2,"tg": "840539006","vp": "1119305005"}],
"dob": "1977-01-04","nam": {"fn": "SMITH","gn": "FRED SMITH",
"fnt": "SMITH","gnt": "FRED SMITH"},"ver": "1.3.0"}}}'

The code is [here]:

import zlib
import base45
from cose.messages import CoseMessage
from binascii import unhexlify, hexlify
from cose.messages import Sign1Message
from cose.keys import CoseKey
from cose.headers import Algorithm, KID
from cose.algorithms import EdDSA
from cose.keys.curves import Ed25519
from cose.keys.keyparam import KpKty, OKPKpD, OKPKpX, KpKeyOps, OKPKpCurve
from cose.keys.keytype import KtyOKP
from cose.keys.keyops import SignOp, VerifyOp
msg = Sign1Message(phdr = {Algorithm: EdDSA, KID: b'kid2'},payload = message.encode())
cose_key = {KpKty: KtyOKP,OKPKpCurve: Ed25519,KpKeyOps: [SignOp, VerifyOp],OKPKpD: unhexlify(b'9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60'),OKPKpX: unhexlify(b'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a')}
cose_key = CoseKey.from_dict(cose_key)
msg.key = cose_key
en = msg.encode(tag=True,sign=True)

After this we compress with zlib, and then encode with Base-45:

compressed = zlib.compress(en)
encoded = base45.b45encode(compressed)
print ("Code: ",encoded.decode())

This then gives us the code for the QR code. In this case it is:

6BFX A0087I0ZQ2M95*7DF.4 4JUZ1U0OC0OL-5RO3E9VR/BVBKBPD*62: D*OH+$2$XEU-RI7A18PFNH-:DVN7 VJWBKB%JHBWN.D0-D2$4NV23QIH6O+P9N*SR:4*O3+:TH%D4R9H7D-%MIQ4OWDNTC6D261HBHQ445L52GG48TLY4QDEBYAK194L/STCA7M1KR61P8DSHW069.QN-G3 MHBJV.CI588 STC55J22Z9M2H%41R10REKDRI M9XAP8%ROZHKIA6*L5JNDU2JUII5LNV0MF7PI7RR35WT Y9E*SE:NV%LKHJ *8I40SDIA+G2X6EXQ.53/65.GQTG13M9%OQZPU .QS/DPIPG30$RIR226V8GCO566H7OK0PM+IIG15QQWKP9FM3ZN0XFIY9+2I09LXSMKOIE/0KSJ29LV%5LUL4BW:+B-J6RWPIEDL.RPO0CZ2CVSQAWIIVAETH3T  49E3YOREXJ.0P7FV5Z88DWXKUJWVRGD2T36MB5RAHYUQUL712W6S3Y9Z-TC4VY5SYTBGS361S6XR%AB.WVVFS++F

We then add “HC1:” to the string, and this is then simply written as a QR code. To decode, we read the QR code data and then decode the Base-45, decompress, and check the signature:

decoded = base45.b45decode(encoded.decode())
# decompress using zlib
decompressed = zlib.decompress(decoded)
cos = CoseMessage.decode(decompressed)
cos.key = cose_key
print ("Signature: ",cos.verify_signature())
print (cos.payload.decode())

Creating a QR code

Possibly one of the easiest ways to create a QR code within a program is to use PowerShell. Overall, PowerShell runs on most computer systems, and you can either create a script (normally with a .ps1 extension) or run it in the command terminal. For the generation of QR codes, we can install this component:

Install-Module -Name QRCodeGenerator

With PowerShell, we can create a QR code graphic in PNG format so that it can be scanned by a smart device and can then connect to a Wifi access point of given SSID and password [here]:

$wifi=$Args[0]
$p=$Args[1]
$imgfile=$Args[2]


Set-ExecutionPolicy Unrestrict
Import-Module QRCodeGenerator
New-QRCodeWifiAccess -SSID $wifi -Password $p -OutPath $imgfile

For an SSID to "home" and a password of "password" [here]:

We can now create a vCard with some details [here]:

$first=$Args[0]
$last=$Args[1]
$company=$Args[2]
$email=$Args[3]
$imgfile=$Args[4]
'First: ',$first
'Last: ',$last
'Email: ',$email
'Company: ',$company
Set-ExecutionPolicy Unrestrict
Import-Module QRCodeGenerator
New-QRCodeVCard -FirstName $first -LastName $last -Company $company -Email $email -OutPath $imgfile

For a first name of “Fred” and last name of “Smith” [here]:

We can use PowerShell to create a QR code to define a location on a map with a longitude and a latitude [here]:

$lt=$Args[0]
$lg=$Args[1]
$imgfile=$Args[2]
$comma=","
$address=$lt, $lg -join ","
'Address: ',$address

Set-ExecutionPolicy Unrestrict
Import-Module QRCodeGenerator
New-QRCodeGeolocation -Address $address -OutPath $imgfile

Here is the location of the Merchiston Campus at Edinburgh Napier University (my workplace) [here]:

Another common application is to create a QR code to define a link to a URI [here]:

$uri=$Args[0]
$imgfile=$Args[1]
'URL: ',$uri
Set-ExecutionPolicy Unrestrict
Import-Module QRCodeGenerator
New-QRCodeURI -URI $uri -OutPath $imgfile

Here is a link to the PowerShell page on ASecuritySite.com [here]:

And, finally, just some text in a QR code [here]:

$text=$Args[0]
$imgfile=$Args[1]
'Text: ',$text
Set-ExecutionPolicy Unrestrict
Import-Module QRCodeGenerator
New-PSOneQRCodeText -Text $text -OutPath $imgfile

Here is a link to a message, “A pessimist sees the difficulty in every opportunity. An optimist sees the opportunity in every difficulty — Winston Churchill” [here]:

Conclusions

Let me dream again. One day I will register for a new GP. I will walk in, and the receptionist will ask me to register. I will press a few buttons and generate a QR code. They will scan this in, and an instant message will appear to say that I am now registered, and say that all my details have been registered. When I go to see the GP, they ask me for my weight and height, and again I go to my wallet and generate a QR code and where the GP scans it in and says, “That’s great. All is fine. I will store this in your record”.

How long will it take for this to ever happen?

Well, we are part of an EU project which has developed the GLASS wallet and which puts the control back in the citizen’s hands:

I will be presenting it live here: