Stream: smart/health-cards
Topic: JWS Headers
Richard Braman (FLY.HEALTH) (Apr 27 2021 at 03:40):
Here's another question for the group. When I look at the JWS examples you provide, the header values for zip and type show up when I planainly parse the JWT. When I create the JWS in my code, these headers are "protected" meaningin they only show up if I validate the JWS. IS this a problem?
Josh Mandel (Apr 27 2021 at 03:43):
The term "protected" in the JWS spec means authenticated -- i.e., data that feeds into the digest that's used for creating a signature.
Josh Mandel (Apr 27 2021 at 03:44):
SMART Health Cards uses the JWS compact serialization (those three b64url-encoded strings separated by dots...), and in that serialization all headers are protected. That doesn't mean encrypted or anything -- just "signed over". It sounds like maybe your library is helping you avoid trouble by only showing you the decoded header after validation, to prevent your accidentally "trusting" header fields that haven't been validated. That's fair, but a verifier does need to peek into the headers (and payload!) before validating a Health Card, to extract the key id and issuer.
Josh Mandel (Apr 27 2021 at 03:44):
For reference, https://tools.ietf.org/html/rfc7515#section-3.1 is the source of truth:
In the JWS Compact Serialization, no JWS Unprotected Header is used.
In this case, the JOSE Header and the JWS Protected Header are the
same.
Richard Braman (FLY.HEALTH) (May 19 2021 at 06:22):
so, I have a shc that's passing all the validation exercises except for the JWS zip header, because as this post indicates, the zip header is protected. Is this a bug in the validator?
Here is my shc:
shc:/56762959532654603460292540772804336028702864716745222809286555723727457252633606564212243706667139775528376455295524257255600461382512334542083442422807532608753442593654622460573601064129336112327424350369044321331110425927776571536726202203307410204304072361397572223576275338636343003475090622077203282009541122650573355764774570117423400605723537365003453472121041055745074321282304566770577270772871417560050568310458036441612054635720572728412211753269442922345658506227625227065228453400220630090540255531326860766873637676682162403512203510400704335339612769770938403212720925005731652210400705571061033577215362656341036510230452290774342168660339056222566903555522723732215255263877277212583731664362075822076239306662402822664424122141712156452376620840211132607311742107732374615029080824575803326333072564253076302027120353353558740374334009203545603724063906773807773073747062635934074067267525385632401122375369373927356006632961390326630345254243557627703265662629225972312808242032047220606912313752277172716977562476366345583023281223210530117453525467564353300770123973634168033428537274396435353423607727382300267561434407257566066766033006313722100612043964703542005062327308587131273260395361077724281132602432630037033639093810393777580771527331055523322145235857532275375765552265384330642625344450416655114468713324310712084462647625097642613355065453645273405233635473532672250807296426607340616106740568283869621145397472743931507731215473057324047537443669653474014569403458115533303356072344263276283459642100507271410403222466611131101136642528412043114370743908731069603629086804331208665275763056401141375424110634716229533803712274
here is the error as shown in the validator:
{"message":"JWS header missing 'zip' property.","code":107,"level":3}
Reece Adamson (May 19 2021 at 11:43):
@Richard Braman (FLY.HEALTH) the example you provided appears to be missing the "zip": "DEF"
header.
If we take just the numeric segment of your QR code (56762959...
) and reconstruct the JWS
e.g. in node.js
const numeric = '56762959...'
const decoded = numeric.match(/(..?)/g).map(num => String.fromCharCode(parseInt(num, 10) + 45)).join('') // Split into groups of 2 numeric characters each of which represent a single JWS char
const header = decoded.split('.')[0]
console.log(header)
console.log(Buffer.from(header, 'base64').toString('utf8'))
You'll find that the header is eyJhbGciOiJFUzI1NiIsImtpZCI6InduRHZualQ3eW9ER3otTzdIRmdJdEFudi1jSF9NZW5OWWI4bG5xOWhQckEifQ
Base64 decoding this gives: {"alg":"ES256","kid":"wnDvnjT7yoDGz-O7HFgItAnv-cH_MenNYb8lnq9hPrA"}
You can contrast this with the Example 0 JWS from the spec where the JWS header is eyJ6aXAiOiJERUYiLCJhbGciOiJFUzI1NiIsImtpZCI6IjNLZmRnLVh3UC03Z1h5eXd0VWZVQUR3QnVtRE9QS01ReC1pRUxMMTFXOXMifQ
and is Base64 decoded to {"zip":"DEF","alg":"ES256","kid":"3Kfdg-XwP-7gXyywtUfUADwBumDOPKMQx-iELL11W9s"}
Reece Adamson (May 19 2021 at 11:45):
I also reconstructed the payload and didn't see the "DEF": "zip"
header there either (but it shouldn't be in the payload anyways)
e.g.
Reconstructed Payload
Christian Paquin (May 19 2021 at 13:14):
Richard Braman (FLY.HEALTH) said:
so, I have a shc that's passing all the validation exercises except for the JWS zip header, because as this post indicates, the zip header is protected. Is this a bug in the validator?
Here is my shc: [...]
You are indeed missing the zip header, as you can see when running the validator on the command line:
node . -p qrnumeric.txt -t qrnumeric -l debug
(where qrnumeric.txt contains the code your provided)
JWS-compact
│
├─ Debug
│ · JWS.header = {"alg":"ES256","kid":"wnDvnjT7yoDGz-O7HFgItAnv-cH_MenNYb8lnq9hPrA"}
Josh Mandel (May 19 2021 at 13:39):
I wonder if we should just make zip compression implicit, so it'd be okay for issuers to omit the header. It's not like we provide a way to create a health card without compressing the payload, so the header isn't really communicating information.(In future, if we ever need to describe different encoding options we could add a header like smw: 2
or whatever)
Richard Braman (FLY.HEALTH) (May 19 2021 at 16:56):
I got it working . it was some delicacy in the node-jose library. It works now.
shc:/5676290952432060346029243740446031222959532654603460292540772804336028702864716745222809286555723727457252633606564212243706667139775528376455295524257255600461382512334542083442422807532608753442593654622460573601064131315359332124357641683164721205433161770363323729743636592231672435701033715605205668066470535231125509532723583667282009546433353455254104555740007461400605723537365032205600121004753925074323282312355405250437631242760721441004250774094468595872767358275962686756442629703259273536502221767123105728083300270041037207426464715741533168546970663221581033285059396111127134544270350833767764776543670373241067366108507135074305220629353071721270355566653920092667616345400739033471710329042474635903296360345509626143206945753625742805414028074032445833106069526054672376700840371132377376585907726974585028250824576203326333072564253076305827120345575736740374273641203970756630536753046754633135077070085932114467427525395632031122415269563940676803633361390426630344634243557627723265662629227572312045222026520625567773312152277172716961562438366545585321245659581025544433003444733959631256546706766241713561263166240877067574304053092839750576361065367235525524642164031066065250345256047509067208382311445352757466607307542874223523265931675562332835002464057670034231646974120603742426540923393843301003096670033855326075676921107104636025336563590621713162670474734238036767735312554053042660457327676943221111627723384368397510073368603667633461431131702709730376744373066921295540263435082358013966744233703311673267701263207363746654436657302024660028770339323033202265225523764076720930105326283128430865526074596137753954684168533862550359522142430758445552587158
Last updated: Apr 12 2022 at 19:14 UTC