# Validation and Parsing

**Note**: Parsing and validation of the JWS should happen only in your backend. Doing the parsing on the client side defeats the purpose of our digital signature

## JWS structure

The result is a string representing a JWS Compact Serialization, a representation of the JWS as a compact, URL-safe string, see <https://tools.ietf.org/html/rfc7515> for details. The decoded JWS is composed of a header that defines the algorithm and the token type and the payload that contains the data.

Header example:

```json
{
  "kid": "e49b9f971574455ba969b20697a2c7b6",
  "alg": "RS256"
}
```

The “kid” attribute contains the key identifier that is needed to retrieve the public key to validate the JWS signature, see [JWS validation and parsing](#jws-validation-and-parsing) for details.

#### Enrollment payload example

```json
{
  "aud": "clientid",
  "data": {
    "documents": [
      {
        "face": {
          "auditTrailImageId": "5f290764076cff0e3f7b3a2f",
          "matchLevel": 2,
          "match": true
        },
        "documentType": "PASSPORT",
        "scan": {
          "faceImageId": "5e9960242d35cc7ca0328729",
          "frontImageId": "5e9960232d35cc7ca0328725",
          "back": {},
          "front": {
            "documentCode": "P<",
            "dateOfExpiry": "220315",
            "secondaryId": "MARIO",
            "nationality": "ITA",
            "documentNumber": "YAXXXXXX",
            "mrzVerified": true,
            "sex": "M",
            "dateOfBirth": "800825",
            "opt1": "<<<<<<<<<<<<<<",
            "primaryId": "CASOLA",
            "mrzText": "P<ITACASOLA<<MARIO<<<<<<<<<<<<<<<<<<<<<<<<<<\nYAXXXXXX52ITA8008253M2203159<<<<<<<<<<<<<<00",
            "issuer": "ITA"
          },
          "backImageId": null
        },
        "reading": {
          "data": {
            "mrz": {
              "documentCode": "P",
              "dateOfExpiry": "220315",
              "optionalData2": null,
              "gender": "MALE",
              "nationality": "ITA",
              "documentNumber": "YAXXXXXX",
              "dateOfBirth": "800825",
              "issuingState": "ITA",
              "secondaryIdentifier": "MARIO",
              "primaryIdentifier": "CASOLA",
              "optionalData1": "<<<<<<<<<<<<<<0"
            },
            "countrySigningCertificate": {
              "serialNumber": "1",
              "publicKeyAlgorithm": "RSA",
              "subject": "C=IT,O=MINISTERO DELL'INTERNO,OU=PE,CN=CERTIFICATION AUTHORITY 01",
              "certificateThumbprint": "9cb8d31734faa68009d1f7fef68a5cc802cb8a2e",
              "validFrom": "2011-12-14T10:29:04.000+0000",
              "signatureAlgorithm": "SHA1WITHRSA",
              "issuer": "C=IT,O=MINISTERO DELL'INTERNO,OU=PE,CN=CERTIFICATION AUTHORITY 01",
              "validTo": "2027-03-10T10:29:04.000+0000"
            },
            "ldsVersion": null,
            "documentSigningCertificate": {
              "serialNumber": "464",
              "publicKeyAlgorithm": "RSA",
              "subject": "C=IT,O=MINISTERO DELL'INTERNO,OU=PE,CN=DOCUMENT SIGNER.24",
              "certificateThumbprint": "3f0b7bac9adde63916a2c4ebd0e3f38c916a3a97",
              "validFrom": "2012-03-14T11:02:41.000+0000",
              "signatureAlgorithm": "SHA1WITHRSA",
              "issuer": "C=IT,O=MINISTERO DELL'INTERNO,OU=PE,CN=CERTIFICATION AUTHORITY 01",
              "validTo": "2022-06-15T11:02:41.000+0000"
            },
            "photo": "",
            "dataGroupHashes": [
              {
                "computedHash": "86525f4741b3504765f4100f2ddf9bf1f17380ef",
                "dataGroupNumber": 1,
                "storedHash": "86525f4741b3504765f4100f2ddf9bf1f17380ef",
                "match": true
              },
              {
                "computedHash": "b01c95fc9d381f6a7f5fd9f3fae767ea0d9fd2a0",
                "dataGroupNumber": 2,
                "storedHash": "b01c95fc9d381f6a7f5fd9f3fae767ea0d9fd2a0",
                "match": true
              }
            ],
            "photoMimeType": "image/jp2",
            "validity": {
              "dataGroupHashesSucceeded": true,
              "documentSignerSucceeded": true,
              "countrySignerSucceeded": true,
              "sodSignerSucceeded": true
            }
          }
        }
      }
    ],
    "nonce": ""
  },
  "iss": "https://id.uqudo.io",
  "exp": 1587111760,
  "iat": 1587109960,
  "jti": "5a5cb56b-ef3d-434c-9f86-5ab24c4953ec"
}
```

#### Face Session payload example

```json
{
  "aud": "client_id",
  "data": {
    "face": {
      "auditTrailImageId": "5eabf184827ca836b8e28cf0",
      "matchLevel": 5,
      "match": true
    },
    "sessionId": "962cd61a-87b2-4c53-b415-27c053c9b281"
  },
  "iss": "https://id.uqudo.io",
  "exp": 1588327388,
  "iat": 1588326788,
  "jti": "6049f9c6-756e-48d7-b1ca-bbd00fef7d14"
}
```

## **JWS validation and parsing**

**Note**: Parsing and validation of the JWS should happen only in your backend. Doing the parsing on the client side defeats the purpose of our digital signature

The JWS can be validated using the list of public keys available on <https://id.uqudo.io/api/.well-known/jwks.json>. It is a public endpoint:

```shell
$ curl https://id.uqudo.io/api/.well-known/jwks.json | jq
{
  "keys": [
    {
      "kty": "RSA",
      "e": "AQAB",
      "kid": "e49b9f971574455ba969b20697a2c7b6",
      "alg": "RS256",
      "n": "rEFxuU7IZiiKzyjVQ9U3yW594Hll-jjuWK-vYZBC9JZ4FmWMSsG3auvkpieUjrkMKKEP5YSLbhOOzjcRPRxSEcDfJl7jSD6mvWN05wokYFxUc9RT2p4kOkXPq26Wio4ksVJhFp1dkuJRyPIBW3xT2ipqnDmzUPzC4nKEwZC6vRz0sU4I7fFKLqGf4fmvi2nmJile-ctfcN8GV2Cam84WAgiIg7LrzYFQMeIj0fAmeBUXO4TAddsF6l6_JJu3uDXnzrDYJL9bEZiTk3Anf4SVeTle-hLDeAkTGbHI0Juqf1SEegGMRQ0mM0xcZe7Hmn3CFul3ahfEvGAYyny2tzHNUw"
    }
  ]
}
```

The kid in the JWS header is used to identify the key in the list above.

**Note**: Check <https://jwt.io/libraries> for the best library you can use according to your environment and programming language. Make sure the libary you choose supports JWKs through URL and make sure it caches the list of keys in memory and refresh the cache only if the kid is not found.

Below you can find an example on how to parse and validate the JWS using io.jsonwebtoken:

```java
import io.jsonwebtoken.Jwts;
import com.auth0.jwk.UrlJwkProvider;import yourpackage.JwkKeyResolver;

....

var claims = Jwts.parserBuilder()
    .setSigningKeyResolver(new JwkKeyResolver(new UrlJwkProvider("https://<--server-->/api")))
    .build()
    .parseClaimsJws(jws)
```

Below you can find an example on how to parse and validate the JWS using com.auth0:

```java
import com.auth0.jwk.JwkProvider;
import java.security.Key;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.SigningKeyResolver;

public class JwkKeyResolver implements SigningKeyResolver {

    private final JwkProvider keyStore;

    public JwkKeyResolver(JwkProvider keyStore) {
        this.keyStore = keyStore;
    }

    @Override
    public Key resolveSigningKey(JwsHeader header, Claims claims) {
        return this.getKey(header);
    }

    @Override
    public Key resolveSigningKey(JwsHeader header, String plaintext) {
        return this.getKey(header);
    }

    private Key getKey(JwsHeader header) throws Exception {
        var keyId = header.getKeyId();
        return keyStore.get(keyId).getPublicKey();
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.uqudo.com/docs/kyc/uqudo-sdk/sdk-result/validation-and-parsing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
