Verify JWS

Code Samples

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)

}
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");
}
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!")

Last updated