From 3557b43fb87fb5751215ab86438dbce69a5e28e0 Mon Sep 17 00:00:00 2001
From: Florian Kaufmann <florian.kaufmann@codecentric.de>
Date: Thu, 25 Nov 2021 11:30:44 +0100
Subject: [PATCH] Verschieben der Addressinformations Validationsinformationen

---
 docs/getting-started/receiving/routing.mdx    | 132 ------------------
 .../sending/get-destination.mdx               | 132 ++++++++++++++++++
 .../getting-started/receiving/routing.mdx     | 132 ------------------
 .../sending/get-destination.mdx               | 132 ++++++++++++++++++
 4 files changed, 264 insertions(+), 264 deletions(-)

diff --git a/docs/getting-started/receiving/routing.mdx b/docs/getting-started/receiving/routing.mdx
index f73be9a61..5f44d084a 100644
--- a/docs/getting-started/receiving/routing.mdx
+++ b/docs/getting-started/receiving/routing.mdx
@@ -18,135 +18,3 @@ Von der Zwischenablage können diese Informationen dann in das zuständige Redak
 </div>
 
 Nach der Übernahme der Adressierungsinformationen in das Redaktionssystem werden diese im Format XZuFi an das [Onlinegateway des Portalverbund (PVOG)](https://servicesuche.bund.de/) übermittelt und sind anschließend [über die Routing API abrufbar](../sending/get-destination.mdx).
-
-### Inhalt der Adressierungsinformationen
-Der dekodierte Inhalt (Payload) der Adressierungsinformationen sieht beispielhaft wie folgt aus (Leerzeichen und Zeilenumbrüche dienen ausschließlich der besseren Lesbarkeit):
-```json
-{
-  "submissionHost": "submission-api-testing.fit-connect.fitko.dev",
-  "iss": "https://portal.auth-testing.fit-connect.fitko.dev",
-  "services": [
-    {
-      "gebietIDs": [
-        "urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs:12345"
-      ],
-      "leistungIDs": [
-        "urn:de:fim:leika:leistung:100"
-      ]
-    }
-  ],
-  "destinationId": "0c438057-ec3e-4ce0-b154-1683b5d3c2e8",
-  "iat": 1637685592,
-  "jti": "ae37e58b-e280-4706-b99e-738f24c8d98f"
-}
-```
-
-### Signaturprüfung der vom Self-Service Portal (SSP) signierten Adressierungsinformationen
-Bei den signierten Adressierungsinformationen handelt es sich um signierte JSON Web Tokens (JWTs).
-Um die Signatur der vom Self-Service-Portal signierten JWTs zu überprüfen, ist es notwendig, auf die verwendeten Schlüssel (im Format JSON Web Key, kurz JWK) zugreifen zu können.
-Das Self-Service-Portal stellt ein JSON Web Key Set (JWKS) öffentlich zugänglich über den Endpunkt `/.well-known/jwks.json` bereit.
-Für unser Testsystem ist das JWKS z.B. [hier](https://portal.auth-testing.fit-connect.fitko.dev/.well-known/jwks.json) verfügbar.
-
-Ein Beispiel für ein JWKS ist in folgendem Ausschnitt dargestellt:
-```json
-{
-  "keys": [
-    {
-      "alg": "PS512",
-      "e": "AQAB",
-      "key_ops": [
-        "verify"
-      ],
-      "kid": "6508dbcd-ab3b-4edb-a42b-37bc69f38fed",
-      "kty": "RSA",
-      "n": "65rmDz943SDKYWt8KhmaU…ga16_y9bAdoQJZRpcRr3_v9Q"
-    },
-    {
-      "alg": "PS512",
-      "e": "AQAB",
-      "key_ops": [
-        "verify"
-      ],
-      "kid": "14a70431-01e6-4d67-867d-d678a3686f4b",
-      "kty": "RSA",
-      "n": "wnqKgmQHSqJhvCfdUWWyi8q…yVv3TrQVvGtsjrJVjvJR-s_D7rWoBcJVM"
-    }
-  ]
-}
-```
-
-Mit diesem JWKS kann die Signatur der Adressierungsinformationen überprüft werden.
-Hierfür muss der Schlüssel mit der passenden Schlüssel-ID (Key-ID) aus dem `kid`-Header der Adressierungsinformationen im JWKS ermittelt werden.
-Dann kann man mit diesem und einer entsprechenden Bibliothek eine Signaturprüfung durchführen.
-
-<Tabs
-  defaultValue="java"
-  values={[
-    { label: 'Java (Spring)', value: 'java', },
-  ]
-}>
-<TabItem value="java">
-
-Im folgenden Beispiel wird die Bibliothek [nimbus-jose-jwt](https://connect2id.com/products/nimbus-jose-jwt) für die Prüfung genutzt.
-
-```java
-SignedJWT signedJWT = SignedJWT.parse(eventToken);
-UUID keyId = UUID.fromString(signedJWT.getHeader().getKeyID());
-
-validateTokenStructure(signedJWT);
-
-verifySSPSignature(signedJWT, keyId)
-```
-
-```java
-boolean validateTokenStructure(SignedJWT signedJWT) {
-  try {
-    validateHeader(signedJWT.getHeader());
-    validatePayload(signedJWT.getJWTClaimsSet());
-  } catch (ParseException e) {
-    throw new RuntimeException("The payload of the SET could not get parsed properly.");
-  }
-}
-
-private void validateHeader(JWSHeader header) {
-  validateTrueOrElseThrow(header.getAlgorithm() == JWSAlgorithm.PS512, "The provided alg in the SET header is not allowed.");
-  validateTrueOrElseThrow(header.getType().toString().equals("jwt"), "The provided typ in the SET header is not jwt");
-  validateTrueOrElseThrow(header.getKeyID() != null, "The kid the SET was signed with is not set.");
-}
-
-private void validatePayload(JWTClaimsSet payload) throws ParseException {
-  validateTrueOrElseThrow(payload.getClaim("iss") != null, "The claim iss is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("iat") != null, "The claim iat is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("jti") != null, "The claim jti is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("destinationId") != null, "The claim destinationId is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("submissionHost") != null, "The claim submissionHost is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("services") != null, "The claim services is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getJSONObjectClaim("services").keySet().size() >= 1, "At least one service is needed.");
-}
-
-private void validateTrueOrElseThrow(boolean expression, String msg) {
-  if (!expression) {
-    throw new RuntimeException(msg);
-  }
-}
-```
-
-```java
-static final SSP_BASE_URL = "https://portal.auth-testing.fit-connect.fitko.dev";
-
-boolean verifySSPSignature(SignedJWT signedJWT, String keyId) {
-
-  JWKSet jwks = JWKSet.load(SSP_BASE_URL + "/.well-known/jwks.json");
-  JWK publicKey = jwks.getKeyByKeyId(keyId)
-
-  if (publicKey.getAlgorithm() != JWSAlgorithm.PS512) {
-    throw new RuntimeException("The key specified for signature verification doesn't use/specify PS512 as algorithm.")
-  }
-
-  JWSVerifier jwsVerifier = new RSASSAVerifier(publicKey.toRSAKey());
-  return signedJWT.verify(jwsVerifier);
-}
-```
-
-</TabItem>
-</Tabs>
diff --git a/docs/getting-started/sending/get-destination.mdx b/docs/getting-started/sending/get-destination.mdx
index 35cb1a894..3d9da4d79 100644
--- a/docs/getting-started/sending/get-destination.mdx
+++ b/docs/getting-started/sending/get-destination.mdx
@@ -121,6 +121,138 @@ Beispiel für die Response:
 }
 ```
 
+### Inhalt der Adressierungsinformationen (Parameter `destinationSignature`)
+Der dekodierte Inhalt (Payload) der Adressierungsinformationen sieht beispielhaft wie folgt aus (Leerzeichen und Zeilenumbrüche dienen ausschließlich der besseren Lesbarkeit):
+```json
+{
+  "submissionHost": "submission-api-testing.fit-connect.fitko.dev",
+  "iss": "https://portal.auth-testing.fit-connect.fitko.dev",
+  "services": [
+    {
+      "gebietIDs": [
+        "urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs:12345"
+      ],
+      "leistungIDs": [
+        "urn:de:fim:leika:leistung:100"
+      ]
+    }
+  ],
+  "destinationId": "0c438057-ec3e-4ce0-b154-1683b5d3c2e8",
+  "iat": 1637685592,
+  "jti": "ae37e58b-e280-4706-b99e-738f24c8d98f"
+}
+```
+
+### Signaturprüfung der vom Self-Service Portal (SSP) signierten Adressierungsinformationen (Parameter `destinationSignature`)
+Bei den signierten Adressierungsinformationen handelt es sich um signierte JSON Web Tokens (JWTs).
+Um die Signatur der vom Self-Service-Portal signierten JWTs zu überprüfen, ist es notwendig, auf die verwendeten Schlüssel (im Format JSON Web Key, kurz JWK) zugreifen zu können.
+Das Self-Service-Portal stellt ein JSON Web Key Set (JWKS) öffentlich zugänglich über den Endpunkt `/.well-known/jwks.json` bereit.
+Für unser Testsystem ist das JWKS z.B. [hier](https://portal.auth-testing.fit-connect.fitko.dev/.well-known/jwks.json) verfügbar.
+
+Ein Beispiel für ein JWKS ist in folgendem Ausschnitt dargestellt:
+```json
+{
+  "keys": [
+    {
+      "alg": "PS512",
+      "e": "AQAB",
+      "key_ops": [
+        "verify"
+      ],
+      "kid": "6508dbcd-ab3b-4edb-a42b-37bc69f38fed",
+      "kty": "RSA",
+      "n": "65rmDz943SDKYWt8KhmaU…ga16_y9bAdoQJZRpcRr3_v9Q"
+    },
+    {
+      "alg": "PS512",
+      "e": "AQAB",
+      "key_ops": [
+        "verify"
+      ],
+      "kid": "14a70431-01e6-4d67-867d-d678a3686f4b",
+      "kty": "RSA",
+      "n": "wnqKgmQHSqJhvCfdUWWyi8q…yVv3TrQVvGtsjrJVjvJR-s_D7rWoBcJVM"
+    }
+  ]
+}
+```
+
+Mit diesem JWKS kann die Signatur der Adressierungsinformationen überprüft werden.
+Hierfür muss der Schlüssel mit der passenden Schlüssel-ID (Key-ID) aus dem `kid`-Header der Adressierungsinformationen im JWKS ermittelt werden.
+Dann kann man mit diesem und einer entsprechenden Bibliothek eine Signaturprüfung durchführen.
+
+<Tabs
+  defaultValue="java"
+  values={[
+    { label: 'Java (Spring)', value: 'java', },
+  ]
+}>
+<TabItem value="java">
+
+Im folgenden Beispiel wird die Bibliothek [nimbus-jose-jwt](https://connect2id.com/products/nimbus-jose-jwt) für die Prüfung genutzt.
+
+```java
+SignedJWT signedJWT = SignedJWT.parse(eventToken);
+UUID keyId = UUID.fromString(signedJWT.getHeader().getKeyID());
+
+validateTokenStructure(signedJWT);
+
+verifySSPSignature(signedJWT, keyId)
+```
+
+```java
+boolean validateTokenStructure(SignedJWT signedJWT) {
+  try {
+    validateHeader(signedJWT.getHeader());
+    validatePayload(signedJWT.getJWTClaimsSet());
+  } catch (ParseException e) {
+    throw new RuntimeException("The payload of the SET could not get parsed properly.");
+  }
+}
+
+private void validateHeader(JWSHeader header) {
+  validateTrueOrElseThrow(header.getAlgorithm() == JWSAlgorithm.PS512, "The provided alg in the SET header is not allowed.");
+  validateTrueOrElseThrow(header.getType().toString().equals("jwt"), "The provided typ in the SET header is not jwt");
+  validateTrueOrElseThrow(header.getKeyID() != null, "The kid the SET was signed with is not set.");
+}
+
+private void validatePayload(JWTClaimsSet payload) throws ParseException {
+  validateTrueOrElseThrow(payload.getClaim("iss") != null, "The claim iss is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("iat") != null, "The claim iat is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("jti") != null, "The claim jti is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("destinationId") != null, "The claim destinationId is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("submissionHost") != null, "The claim submissionHost is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("services") != null, "The claim services is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getJSONObjectClaim("services").keySet().size() >= 1, "At least one service is needed.");
+}
+
+private void validateTrueOrElseThrow(boolean expression, String msg) {
+  if (!expression) {
+    throw new RuntimeException(msg);
+  }
+}
+```
+
+```java
+static final SSP_BASE_URL = "https://portal.auth-testing.fit-connect.fitko.dev";
+
+boolean verifySSPSignature(SignedJWT signedJWT, String keyId) {
+
+  JWKSet jwks = JWKSet.load(SSP_BASE_URL + "/.well-known/jwks.json");
+  JWK publicKey = jwks.getKeyByKeyId(keyId)
+
+  if (publicKey.getAlgorithm() != JWSAlgorithm.PS512) {
+    throw new RuntimeException("The key specified for signature verification doesn't use/specify PS512 as algorithm.")
+  }
+
+  JWSVerifier jwsVerifier = new RSASSAVerifier(publicKey.toRSAKey());
+  return signedJWT.verify(jwsVerifier);
+}
+```
+
+</TabItem>
+</Tabs>
+
 :::note Hinweis
 Sofern eine Destination-ID und die Adresse des zuständigen Zustelldienstes bereits bekannt sind, können die in einem Zustellpunkt hinterlegten technischen Parameter auch über den Endpunkt <ApiLink to="/v1/destinations/{destinationId}" /> der Submission API des zuständigen Zustelldienstes angefragt werden.
 :::
diff --git a/versioned_docs/version-FIT-Connect_v1/getting-started/receiving/routing.mdx b/versioned_docs/version-FIT-Connect_v1/getting-started/receiving/routing.mdx
index f73be9a61..5f44d084a 100644
--- a/versioned_docs/version-FIT-Connect_v1/getting-started/receiving/routing.mdx
+++ b/versioned_docs/version-FIT-Connect_v1/getting-started/receiving/routing.mdx
@@ -18,135 +18,3 @@ Von der Zwischenablage können diese Informationen dann in das zuständige Redak
 </div>
 
 Nach der Übernahme der Adressierungsinformationen in das Redaktionssystem werden diese im Format XZuFi an das [Onlinegateway des Portalverbund (PVOG)](https://servicesuche.bund.de/) übermittelt und sind anschließend [über die Routing API abrufbar](../sending/get-destination.mdx).
-
-### Inhalt der Adressierungsinformationen
-Der dekodierte Inhalt (Payload) der Adressierungsinformationen sieht beispielhaft wie folgt aus (Leerzeichen und Zeilenumbrüche dienen ausschließlich der besseren Lesbarkeit):
-```json
-{
-  "submissionHost": "submission-api-testing.fit-connect.fitko.dev",
-  "iss": "https://portal.auth-testing.fit-connect.fitko.dev",
-  "services": [
-    {
-      "gebietIDs": [
-        "urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs:12345"
-      ],
-      "leistungIDs": [
-        "urn:de:fim:leika:leistung:100"
-      ]
-    }
-  ],
-  "destinationId": "0c438057-ec3e-4ce0-b154-1683b5d3c2e8",
-  "iat": 1637685592,
-  "jti": "ae37e58b-e280-4706-b99e-738f24c8d98f"
-}
-```
-
-### Signaturprüfung der vom Self-Service Portal (SSP) signierten Adressierungsinformationen
-Bei den signierten Adressierungsinformationen handelt es sich um signierte JSON Web Tokens (JWTs).
-Um die Signatur der vom Self-Service-Portal signierten JWTs zu überprüfen, ist es notwendig, auf die verwendeten Schlüssel (im Format JSON Web Key, kurz JWK) zugreifen zu können.
-Das Self-Service-Portal stellt ein JSON Web Key Set (JWKS) öffentlich zugänglich über den Endpunkt `/.well-known/jwks.json` bereit.
-Für unser Testsystem ist das JWKS z.B. [hier](https://portal.auth-testing.fit-connect.fitko.dev/.well-known/jwks.json) verfügbar.
-
-Ein Beispiel für ein JWKS ist in folgendem Ausschnitt dargestellt:
-```json
-{
-  "keys": [
-    {
-      "alg": "PS512",
-      "e": "AQAB",
-      "key_ops": [
-        "verify"
-      ],
-      "kid": "6508dbcd-ab3b-4edb-a42b-37bc69f38fed",
-      "kty": "RSA",
-      "n": "65rmDz943SDKYWt8KhmaU…ga16_y9bAdoQJZRpcRr3_v9Q"
-    },
-    {
-      "alg": "PS512",
-      "e": "AQAB",
-      "key_ops": [
-        "verify"
-      ],
-      "kid": "14a70431-01e6-4d67-867d-d678a3686f4b",
-      "kty": "RSA",
-      "n": "wnqKgmQHSqJhvCfdUWWyi8q…yVv3TrQVvGtsjrJVjvJR-s_D7rWoBcJVM"
-    }
-  ]
-}
-```
-
-Mit diesem JWKS kann die Signatur der Adressierungsinformationen überprüft werden.
-Hierfür muss der Schlüssel mit der passenden Schlüssel-ID (Key-ID) aus dem `kid`-Header der Adressierungsinformationen im JWKS ermittelt werden.
-Dann kann man mit diesem und einer entsprechenden Bibliothek eine Signaturprüfung durchführen.
-
-<Tabs
-  defaultValue="java"
-  values={[
-    { label: 'Java (Spring)', value: 'java', },
-  ]
-}>
-<TabItem value="java">
-
-Im folgenden Beispiel wird die Bibliothek [nimbus-jose-jwt](https://connect2id.com/products/nimbus-jose-jwt) für die Prüfung genutzt.
-
-```java
-SignedJWT signedJWT = SignedJWT.parse(eventToken);
-UUID keyId = UUID.fromString(signedJWT.getHeader().getKeyID());
-
-validateTokenStructure(signedJWT);
-
-verifySSPSignature(signedJWT, keyId)
-```
-
-```java
-boolean validateTokenStructure(SignedJWT signedJWT) {
-  try {
-    validateHeader(signedJWT.getHeader());
-    validatePayload(signedJWT.getJWTClaimsSet());
-  } catch (ParseException e) {
-    throw new RuntimeException("The payload of the SET could not get parsed properly.");
-  }
-}
-
-private void validateHeader(JWSHeader header) {
-  validateTrueOrElseThrow(header.getAlgorithm() == JWSAlgorithm.PS512, "The provided alg in the SET header is not allowed.");
-  validateTrueOrElseThrow(header.getType().toString().equals("jwt"), "The provided typ in the SET header is not jwt");
-  validateTrueOrElseThrow(header.getKeyID() != null, "The kid the SET was signed with is not set.");
-}
-
-private void validatePayload(JWTClaimsSet payload) throws ParseException {
-  validateTrueOrElseThrow(payload.getClaim("iss") != null, "The claim iss is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("iat") != null, "The claim iat is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("jti") != null, "The claim jti is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("destinationId") != null, "The claim destinationId is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("submissionHost") != null, "The claim submissionHost is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getClaim("services") != null, "The claim services is missing in the payload of the JWT.");
-  validateTrueOrElseThrow(payload.getJSONObjectClaim("services").keySet().size() >= 1, "At least one service is needed.");
-}
-
-private void validateTrueOrElseThrow(boolean expression, String msg) {
-  if (!expression) {
-    throw new RuntimeException(msg);
-  }
-}
-```
-
-```java
-static final SSP_BASE_URL = "https://portal.auth-testing.fit-connect.fitko.dev";
-
-boolean verifySSPSignature(SignedJWT signedJWT, String keyId) {
-
-  JWKSet jwks = JWKSet.load(SSP_BASE_URL + "/.well-known/jwks.json");
-  JWK publicKey = jwks.getKeyByKeyId(keyId)
-
-  if (publicKey.getAlgorithm() != JWSAlgorithm.PS512) {
-    throw new RuntimeException("The key specified for signature verification doesn't use/specify PS512 as algorithm.")
-  }
-
-  JWSVerifier jwsVerifier = new RSASSAVerifier(publicKey.toRSAKey());
-  return signedJWT.verify(jwsVerifier);
-}
-```
-
-</TabItem>
-</Tabs>
diff --git a/versioned_docs/version-FIT-Connect_v1/getting-started/sending/get-destination.mdx b/versioned_docs/version-FIT-Connect_v1/getting-started/sending/get-destination.mdx
index 35cb1a894..3d9da4d79 100644
--- a/versioned_docs/version-FIT-Connect_v1/getting-started/sending/get-destination.mdx
+++ b/versioned_docs/version-FIT-Connect_v1/getting-started/sending/get-destination.mdx
@@ -121,6 +121,138 @@ Beispiel für die Response:
 }
 ```
 
+### Inhalt der Adressierungsinformationen (Parameter `destinationSignature`)
+Der dekodierte Inhalt (Payload) der Adressierungsinformationen sieht beispielhaft wie folgt aus (Leerzeichen und Zeilenumbrüche dienen ausschließlich der besseren Lesbarkeit):
+```json
+{
+  "submissionHost": "submission-api-testing.fit-connect.fitko.dev",
+  "iss": "https://portal.auth-testing.fit-connect.fitko.dev",
+  "services": [
+    {
+      "gebietIDs": [
+        "urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs:12345"
+      ],
+      "leistungIDs": [
+        "urn:de:fim:leika:leistung:100"
+      ]
+    }
+  ],
+  "destinationId": "0c438057-ec3e-4ce0-b154-1683b5d3c2e8",
+  "iat": 1637685592,
+  "jti": "ae37e58b-e280-4706-b99e-738f24c8d98f"
+}
+```
+
+### Signaturprüfung der vom Self-Service Portal (SSP) signierten Adressierungsinformationen (Parameter `destinationSignature`)
+Bei den signierten Adressierungsinformationen handelt es sich um signierte JSON Web Tokens (JWTs).
+Um die Signatur der vom Self-Service-Portal signierten JWTs zu überprüfen, ist es notwendig, auf die verwendeten Schlüssel (im Format JSON Web Key, kurz JWK) zugreifen zu können.
+Das Self-Service-Portal stellt ein JSON Web Key Set (JWKS) öffentlich zugänglich über den Endpunkt `/.well-known/jwks.json` bereit.
+Für unser Testsystem ist das JWKS z.B. [hier](https://portal.auth-testing.fit-connect.fitko.dev/.well-known/jwks.json) verfügbar.
+
+Ein Beispiel für ein JWKS ist in folgendem Ausschnitt dargestellt:
+```json
+{
+  "keys": [
+    {
+      "alg": "PS512",
+      "e": "AQAB",
+      "key_ops": [
+        "verify"
+      ],
+      "kid": "6508dbcd-ab3b-4edb-a42b-37bc69f38fed",
+      "kty": "RSA",
+      "n": "65rmDz943SDKYWt8KhmaU…ga16_y9bAdoQJZRpcRr3_v9Q"
+    },
+    {
+      "alg": "PS512",
+      "e": "AQAB",
+      "key_ops": [
+        "verify"
+      ],
+      "kid": "14a70431-01e6-4d67-867d-d678a3686f4b",
+      "kty": "RSA",
+      "n": "wnqKgmQHSqJhvCfdUWWyi8q…yVv3TrQVvGtsjrJVjvJR-s_D7rWoBcJVM"
+    }
+  ]
+}
+```
+
+Mit diesem JWKS kann die Signatur der Adressierungsinformationen überprüft werden.
+Hierfür muss der Schlüssel mit der passenden Schlüssel-ID (Key-ID) aus dem `kid`-Header der Adressierungsinformationen im JWKS ermittelt werden.
+Dann kann man mit diesem und einer entsprechenden Bibliothek eine Signaturprüfung durchführen.
+
+<Tabs
+  defaultValue="java"
+  values={[
+    { label: 'Java (Spring)', value: 'java', },
+  ]
+}>
+<TabItem value="java">
+
+Im folgenden Beispiel wird die Bibliothek [nimbus-jose-jwt](https://connect2id.com/products/nimbus-jose-jwt) für die Prüfung genutzt.
+
+```java
+SignedJWT signedJWT = SignedJWT.parse(eventToken);
+UUID keyId = UUID.fromString(signedJWT.getHeader().getKeyID());
+
+validateTokenStructure(signedJWT);
+
+verifySSPSignature(signedJWT, keyId)
+```
+
+```java
+boolean validateTokenStructure(SignedJWT signedJWT) {
+  try {
+    validateHeader(signedJWT.getHeader());
+    validatePayload(signedJWT.getJWTClaimsSet());
+  } catch (ParseException e) {
+    throw new RuntimeException("The payload of the SET could not get parsed properly.");
+  }
+}
+
+private void validateHeader(JWSHeader header) {
+  validateTrueOrElseThrow(header.getAlgorithm() == JWSAlgorithm.PS512, "The provided alg in the SET header is not allowed.");
+  validateTrueOrElseThrow(header.getType().toString().equals("jwt"), "The provided typ in the SET header is not jwt");
+  validateTrueOrElseThrow(header.getKeyID() != null, "The kid the SET was signed with is not set.");
+}
+
+private void validatePayload(JWTClaimsSet payload) throws ParseException {
+  validateTrueOrElseThrow(payload.getClaim("iss") != null, "The claim iss is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("iat") != null, "The claim iat is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("jti") != null, "The claim jti is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("destinationId") != null, "The claim destinationId is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("submissionHost") != null, "The claim submissionHost is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getClaim("services") != null, "The claim services is missing in the payload of the JWT.");
+  validateTrueOrElseThrow(payload.getJSONObjectClaim("services").keySet().size() >= 1, "At least one service is needed.");
+}
+
+private void validateTrueOrElseThrow(boolean expression, String msg) {
+  if (!expression) {
+    throw new RuntimeException(msg);
+  }
+}
+```
+
+```java
+static final SSP_BASE_URL = "https://portal.auth-testing.fit-connect.fitko.dev";
+
+boolean verifySSPSignature(SignedJWT signedJWT, String keyId) {
+
+  JWKSet jwks = JWKSet.load(SSP_BASE_URL + "/.well-known/jwks.json");
+  JWK publicKey = jwks.getKeyByKeyId(keyId)
+
+  if (publicKey.getAlgorithm() != JWSAlgorithm.PS512) {
+    throw new RuntimeException("The key specified for signature verification doesn't use/specify PS512 as algorithm.")
+  }
+
+  JWSVerifier jwsVerifier = new RSASSAVerifier(publicKey.toRSAKey());
+  return signedJWT.verify(jwsVerifier);
+}
+```
+
+</TabItem>
+</Tabs>
+
 :::note Hinweis
 Sofern eine Destination-ID und die Adresse des zuständigen Zustelldienstes bereits bekannt sind, können die in einem Zustellpunkt hinterlegten technischen Parameter auch über den Endpunkt <ApiLink to="/v1/destinations/{destinationId}" /> der Submission API des zuständigen Zustelldienstes angefragt werden.
 :::
-- 
GitLab