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