Signature Validation
The Identity Profile Report JSON contains a proof object that can be used to verify the integrity of the data. To keep the JSON structure in human-readable form, we use a variation of JSON Web Signature (JWS) with detached payload format. This means that instead of carrying the JSON payload in the JWS, it can be attached to the payload as the proof.jws field value, while keeping the payload as it was signed.
Below is the proof object structure:
"proof": { "jws": "<encoded_signature>", "public_key_url": "<url_for_public_key>"}Verification process
Verifying the signature and data integrity can be achieved by the following:
- Retain the
proof.jwsvalue from the Identity Profile Report. - Change the
proof.jwsvalue to an empty string (““) in the Report JSON. - Canonicalise the report according to RFC 8785.
- Verify the signature against the key that’s obtained by resolving
proof.public_key_url.
Example code
x
const fs = require('fs');const axios = require('axios');const jose = require('jose');const { canonicalize } = require('json-canonicalize');// Load the JSON data from the fileconst report = JSON.parse(fs.readFileSync('identity_profile_report.json', 'utf8'));// Extract the proof.jws value and the proof.public_key_urlconst jwsToken = report.proof.jws;const publicKeyUrl = report.proof.public_key_url;// Set the proof.jws value to an empty stringreport.proof.jws = "";// Canonicalize the JSON data according to RFC 8785const canonicalizedReport = canonicalize(report);// Base64url encode the canonicalized JSON dataconst encodedPayload = Buffer.from(canonicalizedReport, 'utf8').toString('base64url');// Decode the JWS tokenconst [protectedHeader, , signature] = jwsToken.split('.');// Fetch the public key from the proof.public_key_urlaxios.get(publicKeyUrl) .then(async response => { const publicKeyJwk = response.data.keys[0]; // Import the public key using jose.importJWK const key = await jose.importJWK(publicKeyJwk, 'EdDSA'); // Construct the JWS object const jws = { protected: protectedHeader, payload: encodedPayload, signature: signature }; // Verify the JWS signature using the flattenedVerify method try { await jose.flattenedVerify(jws, key, { algorithms: ['EdDSA'] }); console.log("Signature is valid."); } catch (err) { console.error("Signature verification failed:", err); } }) .catch(err => { console.error("Failed to fetch public key:", err); });Reference
- JWS Detached Payload - https://tools.ietf.org/html/rfc7515#appendix-F
- RFC 8785: JSON Canonicalization Scheme (JCS) - https://datatracker.ietf.org/doc/html/rfc8785
- RFC 7517: JSON Web Key (JWK) - https://datatracker.ietf.org/doc/html/rfc7517
Was this page helpful?