# Verify JWS

### Code Samples

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```go
package main

import (
	"fmt"
	"log"

	"github.com/lestrrat-go/jwx/v2/jwa"
	"github.com/lestrrat-go/jwx/v2/jwk"
	"github.com/lestrrat-go/jwx/v2/jws"
)

type Data struct {
	Ver           string `json:"ver"`
	Timestamp     string `json:"timestamp"`
	TxnId         string `json:"txnid"`
	ConsentHandle string `json:"ConsentHandle"`
}

func main() {

	bodyBytes := []byte(`{"ver":"2.0.0","timestamp":"2024-05-10T06:13:09.814Z","txnid":"265ac007-71d4-40e7-91d9-b72491f46c35","ConsentHandle":"465d1f35-f716-484f-a38e-30797d97b525"}`)

	const publicKeyJson = `{
		"kty": "RSA",
		"e": "AQAB",
		"use": "sig",
		"kid": "57ea893e-7e1c-4383-b013-f6c96e3bf776",
		"alg": "RS256",
		"n": "mxfLkK5DVngBOlVDdeFu_OQp3dIcfvHvoB1vU0DXTsTfZqpQa5ry9pI5N5lo5XxB_AUNw2bDPGCZBF6u6NKHsy50DXDfyh4VFz2SoxUQJELphfRwrHeugGsHuF3iyHxaXERyFjxjmzy9c3KKPszo_yzjVvZTfPesdyXRjZTXg-bqNIZbD8SrNDF8U0Nvh9kLlp0cfopbxuO4azts0rs3Z9WJZ-KnccFnEcgPvPkvLicsnlIyl3qUbZWFuoDKFgmItvGiOtwNBFtcwTRegrvbER-9bXByDB67KDryzzvdsLfRvs31snvdXSjF4BfXAXTuccQPLprKoHO0HkTq62b7oQ"
	}`

	publicKey, err := jwk.ParseKey([]byte(publicKeyJson))
	if err != nil {
		fmt.Printf("failed parse key: %sn", err)
		return
	}

	// Check if the target header exists and print its value
	xJwsSignature := "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il0sImtpZCI6IjU3ZWE4OTNlLTdlMWMtNDM4My1iMDEzLWY2Yzk2ZTNiZjc3NiJ9..bogawIsv__rLEutcNBYIpkRC-TysvIGyN9uodR6sL87iMU2X43mJ2_T3Sd9VPGRH7UMJo2yBgFKIVjF1VYol7AVCfs_jqskI8IPZ84S7r7mu8U9YuxM-DJFX1zG-Qnva03SZMaFIpTXEZh7Q0dqvxOJdfk6MJfVZ0xlT_lLaOtU-cjdLIhcI8QazM89Gwfbq1SL33szt1KbDlJ2G4Ah8uN-YDiu7qhyLZRkmlfubiyqVST_dBkIDyF_uSIaeTY_s5nGtPKbN5YEgltT2ScYTt7T5Whg12ZAnVEZmk9ox7DJVYId6XlpJxirdREhg4b6WCQVJcsa2wA54OETyOKR_kg"

	fmt.Printf("Response Header X-Jws-Signature: %s\n", xJwsSignature)

	verified, err := jws.Verify([]byte(xJwsSignature), jws.WithKey(jwa.RS256, publicKey), jws.WithDetachedPayload(bodyBytes))
	if err != nil {
		log.Printf("failed to verify message: %s", err)
		return
	}
	log.Printf("signed message verified! -> %s", verified)

}
```

{% endcode %}

{% code title="Java" overflow="wrap" lineNumbers="true" fullWidth="true" %}

```java
detachedSignature = Received jwsSignature

Payload = received Payload

publicKeyString = entity Certificate of the AA 

public void validateJws(String detachedSignature, String payload, String publicKeyString) {
  try {
    print("jws Validation Started...");
    // Use a JsonWebSignature object to verify the signature
    JsonWebSignature verifierJws = new JsonWebSignature();

    // Set the algorithm constraints based on what is agreed upon or expected from
    // the sender
    print("Setting up the algorithm constraints");

    verifierJws.setAlgorithmConstraints(
        new AlgorithmConstraints(
            AlgorithmConstraints.ConstraintType.WHITELIST,
            AlgorithmIdentifiers.RSA_USING_SHA256));

    if (payload == null) {
      print("Setting up the embedded content as compact serialization");
      // The JWS with embedded content is the compact serialization
      verifierJws.setCompactSerialization(detachedSignature);
    } else {
      print(“Setting up the detached content as compact serialization");
      // The JWS with detached content is the compact serialization
      verifierJws.setCompactSerialization(detachedSignature);

      // The unencoded detached content is the payload
      verifierJws.setPayload(payload);
    }

    JsonWebKey jsonWebKey = JsonWebKey.Factory.newJwk(publicKeyString);
    verifierJws.setKey(jsonWebKey.getKey());

    // The public key is used to verify the signature
    // This should be the public key of the sender.
    print("verifying signature with the public key: {}", publicKeyString);
    if (!verifierJws.verifySignature()) {
      log.error(VALIDATION_OF_JWS_FAILED);
      throw new InvalidSignatureException(
          FIUErrorType
              .SIGNATURE_DOES_NOT_MATCH, SIGNATURE_DOES_NOT_MATCH);
    }

  } catch (Exception e) {
    
  }
  Print("JWS verification process completed");
}
```

{% endcode %}

{% code title="Python" overflow="wrap" lineNumbers="true" fullWidth="true" %}

```python
from joserfc.rfc7797 import deserialize_compact
from joserfc.jwk import RSAKey
import json

# Public Key
public_key = RSAKey.import_key({
    "alg": "RS256",
    "e": "AQAB",
    "kid": "b5a1468b-1bd4-4be6-b505-bf2c8d4df056",
    "kty": "RSA",
    "n": "p6DCZYiVNsq3WRgzCWuFvXTGUs3BeDJydPMQMjyzXoXb-s_tvkquED0IeMcj30oic-W7xAkqAm579b9epk0aB5bkWmfSy1tlnzCnNmIsHxA0QEXI9PuohSHLfNFHIk921ymPNji5mlRpoKHzt4029MZvRAxytTcNNGxA3GvicHZFuHLio7AENfhEAmVSURuZPNQeolTcLjYjiArypLV_vtXdTI9sz0OhHOh8whC82efpfxz69LMm86WkISFSSCGG_gMvjtGonxRnKE-iqvkOv4ol6ksZs8xnbzFT-Cmlt13n6DbHJ7s4ZVmwlX8H8GEFBuiUb9I-YSt8sbA-KUi76w",
    "use": "sig"
})

detached_jws = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImI1YTE0NjhiLTFiZDQtNGJlNi1iNTA1LWJmMmM4ZDRkZjA1NiIsImI2NCI6ZmFsc2V9..UeC-M7l9cVufBTjOgsVlAqryR6v7DlFyDawbWfU6tUNm8UfHbjFNsuuiZ4efl7co2P7zpF1JXmEMhNNX9Fqc3G-oau1Ya1cqG7AHJ19UDhIrDfOrDd7EH9Q2pn-D0HgZ_3lteoWngLyYVnGN1hwNWRwFaxIF94Jierxc0xfGHvRxXHZumdiIszNwHo13ydgdknMYpXsmXSyjmCPmyRRvbL2enPcMTFqOghbWuIr43hcC_BC173h2Sk0b7YfyobERST_wRkhxDS9W4fEvbpVM9jILNUVhAxDksBP98VmVlbpdYmui6D2j025koOOyjgR4YEeIhhe3fEC5QoxTsjA6OA"

# Request Payload
payload = json.dumps({"ver":"1.1.2","timestamp":"2024-04-26T06:53:00.370Z","txnid":"f5e123a9-202c-4c7e-8bfa-9db9eea89ff2","Notifier":{"type":"AA","id":"dashboard-aa-preprod"},"ConsentStatusNotification":{"consentId":"bf32b951-c2db-476c-9bb7-4d5fd9489f98","consentHandle":"23d0adf0-da22-4de8-bad0-1913e16f39cb","consentStatus":"ACTIVE"}}, separators=(',', ':'))

obj = deserialize_compact(detached_jws, public_key, payload)
print("Signature is valid!")
```

{% endcode %}


---

# 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.saafe.in/fiu-module/jws-signature/verify-jws.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.
