[conspire] Checking a CDPH Digital COVID-19 Vaccine Record

Rick Moen rick at linuxmafia.com
Wed Sep 8 18:47:50 PDT 2021


----- Forwarded message from Rick Moen <rick at linuxmafia.com> -----

Date: Wed, 8 Sep 2021 18:39:31 -0700
From: Rick Moen <rick at linuxmafia.com>
To: [a CABAL member]
Cc: Dire Red <deirdre at deirdre.net>
Subject: Re: " Bring your CDC card:  I will check."
Organization: If you lived here, you'd be $HOME already.

Quoting [a CABAL member]

> Another off list response; hope it's OK!

Sure.


> Curious if the attached QR code (which I can produce on my mobile
> phone) would serve in lieu of my vaccination card.  Not to be
> construed as a challenge; I'm simply curious if this QR code is in
> wide use.  I believe it comes from CA State Government.  I have yet to
> have to prove vaccination status to

Short version:  Still unclear on how I personally verify that.
Please come along anyway, and we'll figure it out.

I've been needing to disentangle this problem, because you're not the
first person to raise it.  So, here's my present understanding:

CA Dept. of Public Health signed aboard with SMART Health Card.  Since
doing so, a portal site, https://myvaccinerecord.cdph.ca.gov/ , can
issue you a digital record based on the database record in the state's
immunisation registry.  The digital record gets delivered to the user as
a QR code, such as you sent me.

SMART Health Card Framework was developed by an industry consortium
called Vaccination Credential Initiative (VCI), which in turn was
founded by Commons Project Foundation.  Article:
https://beta.protocol.com/workplace/vaccination-credential-initiative

There are apparently a number of smartphone apps that implement the
SMART Health Card Framework such that they can parse the QR code and 
prove that the attested medical information came from a trusted source
like a major pharmacy.


There are four steps involved in issuing a SMART Health Card:

1.  Prepare the data for the card as a FHIR (Fast Healthcare
Interoperability Resources) bundle in JSON format.  See:
http://registry.fhir.org/fhir

2.  Remove any unnecessary elements and whitespace from the JSON and
compress it using the raw DEFLATE algorithm
(https://en.wikipedia.org/wiki/Deflate).

3.  Use a Elliptic Curve P-256 signing key to create a JSON Web Signature (see:
https://medium.facilelogin.com/jwt-jws-and-jwe-for-not-so-dummies-b63310d201a3) 
from the compressed data.

4.  Provide the card to a patient in a format that can be saved and
distributed (e.g. digital file or printable QR code).

The patient can then store the "card" as a file on a mobile (or other) device 
or on the Internet, or print it out in QR code form, or import it into a
digital wallet.


Detailed here:
https://vishnuravi.medium.com/how-do-verifiable-covid-19-vaccination-records-with-smart-health-cards-work-df099370b27a
https://www.roguelazer.com/2021/06/cdph-digital-vaccine-record/
https://stackoverflow.com/questions/68356564/validation-of-smart-health-card-token-fails


There's an app in iOS called Apple Health that can read SMART Health
Card.

For Android, an app called CommonHealth aka SMART Health Card Verifier
(also available for iOS) provides similar functionality.
https://thecommonsproject.org/smart-health-card-verifier



An app that verifies a SMART Health Card needs to do the following:

Read in the QR image file, use the jsQR library to extract the QR code,
separate the numeric segment, and then convert the numeric segment back
into a JWS.

// adapted from
// https://github.com/dvci/health-cards-walkthrough/blob/main/SMART%20Health%20Cards.ipynb 
// scan QR code from image file
const jsQR = require('jsqr');
const PNG = require('pngjs').PNG;
const imageFile = fs.readFileSync('smart-health-card.png');
const image = PNG.sync.read(imageFile);
const imageData = new Uint8ClampedArray(image.data.buffer);
const scannedQR = jsQR(imageData, image.width, image.height); 

// separate the numeric segment
const numericCode = scannedQR.chunks.filter(chunk => chunk.type ===
"numeric")[0];

// convert from numeric encoding to JWS
const JWSchars = numericChunk.text.match(/(..?)/g);
const JWS = JWSchars.map(num => String.fromCharCode(parseInt(num, 10) + 45)).join('');



Extract the payload and decompress it.




// Split the JWS into its three components
const [ header, payload, signature ] = jws.split('.');

// Decode the payload
const decodedPayload = Buffer.from(payload, 'base64');

// Decompress the card and extract the data into an object
const decompressedCard = zlib.inflateRawSync(decodedPayload);
const card = JSON.parse(decompressedCard.toString());




Read the iss field, which contains the issuer’s Web address. 
This is then used to find the issuer's public key under
/.well-known/jwks.json , which then gets fetched off the Internet.

Since anyone can issue a SMART Health Card, maintain a list of
trusted issuers (trust directory) and verify the contents of the iss
field against this list prior to continuing.  If issuer is trusted,
proceed to download the key and use it to verify the signature.




// use axios to get the key and node-jose to perform verification
const axios = require('axios');
const jose = require('node-jose');

// Get the issuer's URL from the card
const issuer = card.iss;

// Download the public key and verify the signature
const result = 
      await axios.get(`${issuer}/.well-known/jwks.json`);
const keystore = await jose.JWK.asKeyStore(result.data.keys);
const verified = 
      await jose.JWS.createVerify(keystore).verify(jws);




Having verified the card’s authenticity, use the clinical data
within the enclosed FHIR bundle.



// extract the FHIR bundle from the card
const fhirBundle = card.vc.credentialSubject.fhirBundle;

// get the patient resource and print out the patient's name
const patient = fhirBundle.entry[0];
const name = 
      patient.resource.name[0].given.join(" ") + " " +      
      patient.resource.name[0].family;
console.log("Name:", name);

// get the immunization resources, extract the code and dates of each vaccination and print them out
const doses = fhirBundle.entry.slice(1);
doses.forEach(dose =>
    console.log(`Date - ${dose.resource.occurrenceDateTime}, CVX - ${dose.resource.vaccineCode.coding[0].code}`)
);



Example output:

Patient - ALICE S GILBERT
Date - 2021-03-18, CVX - 207
Date - 2021-02-18, CVX - 207


(CVX code 207 stands for the Moderna COVID-19 vaccine.)





So, let's have at your QR code.

I saved your QR code to a file, then used an online QR code scanner at https://qrinfopoint.com/qr-code-scanner/,
getting:


shc:/5 [redacted] 0603460 [redacted]   [redacted]  603460292  [ redacted]  702864716745222809286155305564710341432164324111083963210645240371337721263863367742423708412663394539292955640442562759653725333844612060573601044529333900327424285350226768120869712052420855092024212544317243632035697203053766075505400824685731576436653338687371547169310664291008706210610603200839054040284336002329330906062734255526347064712474624339454174637275706306286559445428772644314543084543263877760973454136365559502820445512283025120066437733433058620307242839735973650772442566584557506365655269690468590625673604437545760576643777052055204442392960606465127333680038212864036908430830080763397465643829396576523555105207392672205574037173425453625207703575282368342012756861533935293558237111544562557568505433676728101245445366544324225028616144231142264152393028387442646562744505423862602745777341385477092065327106086059774342350705034072697559203770596508045775336203776053361212272931233964250463725775577020747071733629720903
53312834630961725058056667212410552264550336050012126223424203740346434343033331257263083143042272371172073320555921524471702273050961092008225960545350262126401065440377035903424211124433377739703867246737213708652141753562257028120642725969256224312658114273207461632611032664573553081143390556356009422600432275436010356312577456415206504568712010216161753206126310446450112042227273102374017230391063397739396509570971304244383163387300045065415768585729447059240922296024652755247444617764726344455539526043222021082228632177376670521241592169525336532354545858



That's the Smart Health Card token.




At that point, I could use some stock Python3 code, at the
roguelazer.com link above, to verify the signature on your SHC and print
out its contents, and maybe prettyprint the enclosed FHIR bundle's
clinical data.

Except, for complicated reasons, I don't right now have a full-blown
python3 environment, _so_, what I'd do for the time being is punt by
having Deirdre (cc'd) feed your QR code into Apple Health.  ;->

It's possible there's proper, well-maintained open source for all this
on real Linux, but I haven't had time to look.


Er, however, for now, there's this online verifier:
https://demo-portals.smarthealth.cards/VerifierPortal.html

Decoding yours, and sort-of indenting the output, gets this:

{"iss":"https://myvaccinerecord.cdph.ca.gov/creds","nbf":1625096898,"vc":
   {"type":["https://smarthealth.cards#health-card","https://smarthealth.cards#immunization","https://smarthealth.cards#covid19"],"credentialSubject":
      {"fhirVersion":"4.0.1","fhirBundle":
         {"resourceType":"Bundle","type":"collection","entry":[
            {"fullUrl":"resource:0","resource":
               {"resourceType":"Patient","name":[
               {"family":"SurnameRedacted","given":["AlsoRedacted"]
            }],"birthDate":"2021-08-07"}   [ redaction note: born yesterday, get it?]
         },
            {"fullUrl":"resource:1","resource":
               {"resourceType":"Immunization","status":"completed","vaccineCode":
                  {"coding":[
                     {"system":"http://hl7.org/fhir/sid/cvx","code":"207"
                  }]
               },"patient":
                  {"reference":"resource:0"
               },"occurrenceDateTime":"2021-01-01","performer":[
                  {"actor":
                     {"display":"KAISER PERMANENTE NCAL"
                  }
               }]
            }
         },
            {"fullUrl":"resource:2","resource":
               {"resourceType":"Immunization","status":"completed","vaccineCode":
                  {"coding":[
                     {"system":"http://hl7.org/fhir/sid/cvx","code":"207"
                  }]
               },"patient":
                  {"reference":"resource:0"
               },"occurrenceDateTime":"2021-02-01","performer":[
                  {"actor":
                     {"display":"KAISER PERMANENTE NCAL"
                  }
               }]
            }
         }]
       }
    }
  }
}


So, there, you're verified.  [rest redacted]


----- End forwarded message -----



More information about the conspire mailing list