IT1:RRQ5 8/60V500GKOG8WA6E+5OPCZQEG/D5ECBPE ED0AFM2E6VCQ/EV9EV3E $E9WEB$CBECP9EY CPED$.
CKWEZED.2DV50 NF19W:5EKV52W0TFQJ01Y%8W+6%9IRE2SJ51VEU95K:AM+61XB2UJ+/81-I0Y3YXABQ9XJQST
CRB7G3Y%D868%$M0DE E30QNSFL64W/V473PWW0. VLK8BJO8VBTEHUDQS9HX3BCOMRFFDE560C.BHJP0000DP$
YPCBNQ2OPPA8XD/N5Z6LNVNEJM* CL8FH7PHRUDVVO5IDEQZ$SM1U-N8U$UZ0KQPBYOSEN4: P2/7+5NECC254I
C7BZCN.0J%BBEOMD645V2RG7+S0.5CCR2JTCCAVVOVN0OT-K63CSR14TARR%N/27AUQ9XNJMVO-0LV5DSJPH2/O
V6MMZ1FLLG17WGDYP51T8W/06:QV43FK7RPC$-1Q+PK%I
IOXIO Tags™️ signatures
Technical details about the signatures used with IOXIO Tags™
Header §
The signed codes start with an identifier to designate that they are an IOXIO Tags™ code, including a version number. Right now the header used is the characters IT1:.
Encoded signed data §
Following the header there is the signed data, encoded in Base45, used commonly in e.g. the EU COVID passports and other standards where QR codes need to be used to represent arbitrary binary data.
The data is signed with COSE (CBOR Object Signing and Encryption), effectively a version of the JOSE system but for CBOR, and CBOR itself is a more efficiently packed binary friendly format similar to JSON.
By parsing the COSE signature without verifying it, you should be able to get the JWKS kid and alg from the COSE header, as well as the payload. You can use the iss from the payload to fetch the product-passport.json, which points to the jwks.json. Once you load that file, you can use the other properties to determine the correct key to verify the signature with.
Check out the verify_code function in our demo application for a full example.
Payload §
Once the COSE data is parsed, you will get the properties of the code, so the iss, product, and id, from it.
The data is signed with COSE (CBOR Object Signing and Encryption), effectively a version of the JOSE system but for CBOR, and CBOR itself is a more efficiently packed binary friendly format similar to JSON.
Parsing process §
- Scan the QR code
- Verify the header - that the first 4 characters match exactly IT1:
- Remove the header from the code
- Base45 decode the code
- Parse the alg and kid from the COSE header, as well as the COSE payload without verifying the signature
- Fetch https://{payload.iss}/.well-known/product-passport.json metadata
- Fetch the JWKS keys from {jwks_url} in the product-passport.json
- Verify the COSE signature matches the key provided via JWKS
- Fetch https://{payload.iss}/.well-known/product-passport/{payload.product}.json for product metadata
- Fetch https://{product_dataspace}.well-known/dataspace/dataspace-configuration.json
- Proceed to do what you wish with the supported_dataproducts from the {payload.product}.json, including e.g. fetching the data products via the product_gateway_url from the dataspace-configuration.json
Check out our Sandbox's dataspace-configuration.json to see what configuration is available for IOXIO dataspaces.
Example signed code §
The line feeds are added to make it easier to see what the code is like, but are not a part of the code. Having extra linefeeds breaks the code.
Printed into a QR code one might look something like this:
Check out the make_cose_code function in our demo application for a full example.
You can check out our IOXIO Tag™ generator and as well as IOXIO Tag™ scanner, and their source code to see how these work in practice.
On this page