gematik lib-vau / lib-vau-csharp
VAU-Handshake führt nur 2 von 6 vorgeschriebenen Server-Schlüssel-Prüfungen aus
lib-vau und lib-vau-csharp sind die Referenzimplementierungen des VAU-Protokolls von gematik — der Sicherheitsschicht, die den Datenverkehr zum Backend der elektronischen Patientenakte (ePA) Deutschlands schützt und seit 2025 für die rund 73 Millionen gesetzlich Versicherten im Einsatz ist, sofern sie nicht widersprochen haben. Beide Referenz-VAU-Clients deserialisieren die SignedPublicVauKeys-Struktur des Servers während Message 2 des Handshakes, lesen jedoch die Felder signatureEs256, certHash und ocspResponse nie aus. Von den sechs Prüfschritten, die gemSpec_Krypt A_24624-01 verlangt (Kettenprüfung, OCSP, Rollen-OID, ES256-Signatur, Schlüsselformat, Ablauf), werden nur Schlüsselformat und Ablauf geprüft. Die Bibliotheken bieten Konsumenten keine API, um die Prüfung selbst einzuhängen. Ein netzwerkpositionierter MITM innerhalb des TI- / Klinik-Netzwerk-Segments vor dem VAU-Endpunkt — also genau an der Grenze, gegen die die innere VAU-Schicht eigentlich härten soll — kann daher eigene ECDH- und Kyber-Public-Keys in Message 2 einschleusen und allen nachfolgenden VAU-Verkehr entschlüsseln oder modifizieren. Erfasst als MS-LIB-VAU-eaea8d (Java) und MS-LIB-VAU-CSHARP-9c69c4 (C#).
Beschreibung
gemSpec_Krypt A_24624-01 verlangt vom VAU-Client sechs Prüfschritte auf den SignedPublicVauKeys des Servers während des Handshakes: Zertifikatsketten-Prüfung gegen den TI-PKI-Root, OCSP-Sperrprüfung (max. 24 h), Rollen-OID-Prüfung (oid_epa_vau), ES256-Signaturprüfung über das Schlüsselmaterial, ECC/Kyber-Schlüsselformat-Validierung und Ablaufprüfung (exp > now). Beide Referenzimplementierungen führen nur die letzten beiden aus.
In der Java-Referenzimplementierung (lib-vau) befindet sich die Lücke im Handshake hier:
lib-vau VauClientStateMachine.java:108-120
SignedPublicVauKeys signedPublicVauKeys;try { signedPublicVauKeys = decodeCborMessageToClass( transferredSignedServerPublicKey, SignedPublicVauKeys.class);} catch (Exception e) { throw new IllegalArgumentException( "Could not CBOR decode Signed Server Public Keys...", e);}
VauPublicKeys transferredSignedServerPublicKeyList = signedPublicVauKeys.extractVauKeys();checkCertificateExpired( transferredSignedServerPublicKeyList.getExp());verifyClientMessageIsWellFormed( transferredSignedServerPublicKeyList.getEcdhPublicKey(), transferredSignedServerPublicKeyList);// Proceeds directly to KEM encapsulation with unverified keys.Die Datenklasse SignedPublicVauKeys deserialisiert die relevanten Felder, liest sie aber nie aus:
lib-vau SignedPublicVauKeys.java:45-58
@JsonProperty("signature-ES256")byte[] signatureEs256;
@JsonProperty("cert_hash")byte[] certHash;
@JsonProperty("ocsp_response")byte[] ocspResponse;Die Klasse stellt eine sign()-Methode für die Server-Seite bereit, jedoch keine entsprechende verify()-Methode, und auch keine Schnittstelle oder Callback, über die Konsumenten eine Prüfung von außen einhängen könnten. Die README erklärt "Es werden keine Zertifikate geprüft." — die Bibliothek bietet keine eingebaute Prüfung und keine Schnittstelle, über die Konsumenten sie einhängen können.
Die C#-Referenzimplementierung (lib-vau-csharp) hat dieselbe Form:
lib-vau-csharp VauClientStateMachine.cs:109-113
SignedPublicVauKeys signedPublicVauKeysClient = SignedPublicVauKeys.fromCbor(transferredSignedServerPublicKey);VauPublicKeys transferredSignedServerPublicKeyList = signedPublicVauKeysClient.ExtractVauKeys();KeyUtils.CheckCertificateExpired(transferredSignedServerPublicKeyList.Exp);KeyUtils.VerifyClientMessageIsWellFormed(transferredSignedServerPublicKeyList.EcdhPublicKey, transferredSignedServerPublicKeyList);// Proceeds directly to KEM encapsulation with unverified keys.lib-vau-csharp SignedPublicVauKeys.cs:33-36
readonly byte[] SignatureEs256;readonly byte[] CertHash;readonly byte[] OcspResponse;A_24624-01-Umsetzungsstand über beide Bibliotheken:
A_24624-01 Umsetzungsstand
Anforderung Java C#----------------------------------------------------------OCSP-Prüfung (max. 24 h) Fehlend FehlendZertifikatskette zum TI-PKI-Root Fehlend FehlendRollen-OID oid_epa_vau Fehlend FehlendES256-Signaturprüfung Fehlend FehlendECC/Kyber-Schlüsselformat-Validierung Vorhanden VorhandenAblaufprüfung (exp > now) Vorhanden VorhandenKonsumenten übernehmen die Referenzimplementierung wie sie ist. Die fehlende Prüfung hat sich in produktive Clients fortgepflanzt: med-united/epa4all bindet lib-vau als Submodul ein und übernimmt die fehlende Prüfung unverändert, und oviva-ag/epa4all-client ergänzte zwar ein SignedPublicKeysTrustValidator-Interface, verwarf jedoch den booleschen Rückgabewert von Signature.verify(), sodass ein Fehlschlag der Signaturprüfung den Validator nicht dazu brachte, false zurückzugeben (CVE-2026-44900). gematiks offizieller Beispielcode in epa4all-examples (v0.1.6, inzwischen archiviert) ruft ebenfalls receiveMessage2() ohne jeden Schritt zur Server-Schlüssel-Prüfung auf.
Auswirkung
- Die innere VAU-Schicht ist dafür konzipiert, Patientendaten gegen die Kompromittierung von TLS-Infrastruktur außerhalb der TEE-Grenze zu schützen. Der Angriff erfordert eine Position innerhalb des TI- / Klinik-Netzwerk-Segments vor dem VAU-Endpunkt — also genau an der Grenze, gegen die die innere VAU-Schicht eigentlich härten soll.
- Aus dieser Position kann ein netzwerkpositionierter MITM Message 1 des Handshakes abfangen, eine KEM-Encapsulation mit den Schlüsseln des Clients durchführen und mit einer Message 2 antworten, die in der AEAD-Payload angreiferkontrollierte ECDH- und Kyber-Public-Keys trägt. Das Feld
signatureEs256kann beliebige Bytes enthalten. - Da der Client weder Signatur noch Zertifikatskette, OCSP-Antwort oder Rollen-OID prüft, leitet er die Session-Keys aus den Schlüsseln des Angreifers ab. Der MITM hält dann beide Hälften der Sitzung und kann jede nachfolgende VAU-Nachricht im Klartext entschlüsseln und neu verschlüsseln: Medikationsdaten, Diagnoseberichte und Verordnungshistorie einer betroffenen Person, gelesen vom ePA-Client, in das ePA-Backend zurückgeschriebene Dokumente sowie die Autorisierungstransaktionen, die den Zugriff auf die Patientenakte steuern.
Abhilfe
Konsumenten, die eine der Bibliotheken produktiv einsetzen, sollten ein SignedPublicKeysTrustValidator-Interface ergänzen (der Name, den Ovivas Fork verwendet, eignet sich gut), das der Konstruktor von VauClientStateMachine *zwingend* vom Konsumenten verlangt. Rufen Sie es in receiveMessage2() vor der KEM-Encapsulation auf. Default-deny — wenn kein Validator bereitgestellt wird, soll der Handshake fehlschlagen, statt ohne Prüfung fortzufahren. Der Validator sollte die vollständige A_24624-01-Kette durchführen: Zertifikat per cert_hash abrufen, OCSP-Antwort validieren, Kette gegen TI-PKI-Roots prüfen, auf die Rollen-OID oid_epa_vau prüfen und die ES256-Signatur über den signierten Schlüsselblock verifizieren. Verwenden Sie den booleschen Rückgabewert von Signature.verify() (Java) bzw. VerifyData() (C#); ein verworfener Rückgabewert entspricht keiner Prüfung.
Checkliste für Betreiber
Prüfen, ob Sie lib-vau / lib-vau-csharp ausliefern.
Wenn Ihr ePA-Client (oder irgendein Produkt, das VAU spricht) lib-vau oder lib-vau-csharp direkt, über einen Fork oder über ein Git-Submodul einbindet, betrifft Sie die Lücke. Zwei produktiv ausgelieferte ePA-Implementierungen haben die fehlende Prüfung unverändert übernommen: med-united/epa4all (lib-vau als Git-Submodul) und oviva-ag/epa4all-client (ein Validator wurde ergänzt, aber falsch verdrahtet — siehe CVE-2026-44900).
Einen Trust-Validator mit Default-deny ergänzen.
Der Konstruktor von
VauClientStateMachinemuss verpflichtend einenSignedPublicKeysTrustValidator-Parameter erhalten, der inreceiveMessage2()vor der KEM-Encapsulation aufgerufen wird. Wenn kein Validator bereitgestellt wird, muss der Handshake fehlschlagen und nicht stillschweigend fortgesetzt werden. Die Konstruktor-Signatur selbst muss geändert werden — Java: einen verpflichtenden Parameter zum bisherigen no-arg-Konstruktor hinzufügen; C#: äquivalente Änderung anVauClientStateMachine().Die vollständige A_24624-01-Kette umsetzen.
Cert-Hash-Lookup, OCSP innerhalb von 24 h, Kette zum TI-PKI-Root, Rollen-OID
oid_epa_vau, ES256-Signaturprüfung über den signierten Schlüsselblock. Alle sechs Prüfungen müssen erfolgreich sein, damit der Handshake fortgesetzt wird. TI-PKI-Root-Zertifikate liegen nicht im Standard-Truststore des Systems — beziehen Sie sie aus der veröffentlichten TI-PKI von gematik (gemSpec_PKI, Anhang — TI-Root-CA) und pinnen Sie sie explizit in Ihrem Validator.Prüfen, dass der boolesche Rückgabewert gelesen wird.
Sowohl Javas
Signature.verify()als auch C#'sVerifyData()liefern bei ungültiger Signaturfalsezurück, statt eine Exception zu werfen. Ein verworfener Rückgabewert entspricht stillschweigendem Pass. Der Oviva-Vorfall (CVE-2026-44900) ist genau dieser Fall.Den Validator mit einer gefälschten Message 2 prüfen.
Bauen Sie einen lokalen VAU-Gegenpart, der auf Message 1 mit einer Message 2 antwortet, die wohlgeformte, aber nicht signierte öffentliche Schlüssel sowie beliebige Bytes im Feld
signatureEs256enthält. Der Client muss den Handshake ablehnen. Falls nicht, ist der Validator nicht eingehängt.
Bewertung im Detail
Referenzen
- gemSpec_Krypt — A_24624-01 (Client-Prüfung der signierten öffentlichen Server-Schlüssel)
- gematik-lib-vau-Repository (Java)
- gematik-lib-vau-csharp-Repository
- gematik-epa4all-examples (archiviert)
- Verwandt: Oviva-epa4all-client-Signaturprüfung verworfen (CVE-2026-44900)
- Verwandt: ePA-VAU-Client-Sicherheit (Übersicht)
So können wir helfen
Wer wir sind
Die Sicherheitsforscher hinter diesem Sicherheitshinweis.

Dr. rer. nat. Simon Weber
Senior Pentester & MedSec-Forscher
Ich evaluiere Ihr SaMD mit derselben branchenprägenden Sicherheitsexpertise, die ich dem BAK MV für die Überarbeitung des B3S-Standards beigetragen habe.
- Promotion über Krankenhaus-Cybersicherheit
- Kritische Schwachstellen in Krankenhaussystemen gefunden
- Alumni der THB MedSec-Forschungsgruppe
- gematik Security Hero

Dipl.-Inf. Volker Schönefeld
Senior Application Security Expert
Als ehemaliger CTO und Entwickler, der zum Pentester wurde, arbeite ich mit Ihrem Team zusammen, um Schwachstellen aufzudecken und Lösungen zu finden, die zu Ihrer Architektur passen.
- 20+ Jahre als CTO, 50+ Mio. App-Downloads
- Architektur und Absicherung großer IoT-Flotten
- Certified Web Exploitation Specialist
- gematik Security Hero
Penetrationstest gesucht?
Machine Spirits ist spezialisiert auf Sicherheitsbewertungen für Medizinprodukte und Gesundheits-IT. Von MDR-Penetrationstests bis C5-Cloud-Compliance helfen wir MedTech-Unternehmen, regulatorische Anforderungen zu erfüllen.
