💡 Voll funktionsfähiges Beispiel auf GitHub verfügbar:
sign-word-with-ml-dsa-certificates-dotnet

Der alte Weg war ein Projektplan

Fragt man, was nötig ist, um Dokumenten‑Signaturen post‑quantum zu machen, erhält man eine Roadmap: Algorithmen evaluieren, eine Bibliothek auswählen, eine Abstraktionsschicht über den Signaturcode schreiben, eine Dual‑Signing‑Phase planen, ein Quartal budgetieren.

Der größte Teil davon gilt nach wie vor für die organisatorische Hälfte – Zertifikatsbeschaffung, Richtlinien, Validator‑Unterstützung. Der Code‑Teil stellte sich als kleiner heraus als die Roadmap vermuten lässt, und das ist wichtig zu wissen, bevor jemand ein Quartal dafür budgetiert.

ML‑DSA‑Signing ist eine GroupDocs.Signature‑Funktion für .NET, die Word‑Dokumente mit Zertifikaten auf Basis von FIPS 204, dem NIST‑Standard für post‑quantum Signaturen, signiert. Sie kam in Version 26.9 heraus und ist aus Sicht des Aufrufcodes einfach eine andere PFX‑Datei.

Es gibt einen besseren Weg

Hier ist die gesamte Code‑Änderung:

using var signature = new Signature(sourcePath);

var options = new DigitalSignOptions(pfxPath)
{
    Password = certificatePassword
};

SignResult result = signature.Sign(outputPath, options);

Das ist derselbe Aufruf, der für ein RSA‑Zertifikat verwendet wird. Der Algorithmus ist eine Eigenschaft des Zertifikats, daher gibt es keine Option, die ihn auswählt, keine Abstraktionsschicht ist nötig und es entsteht kein zweiter Code‑Pfad für die Übergangsphase. Zeigen Sie DigitalSignOptions auf ein ML‑DSA‑PFX und die Ausgabe ist eine ML‑DSA‑Signatur.

Das Auslesen des Zertifikats aus dem Ergebnis ist sinnvoll, wenn mehrere Zertifikate im Spiel sind:

var created = result.Succeeded.OfType<DigitalSignature>().FirstOrDefault();
return created?.Certificate?.Subject ?? "(no certificate returned)";

Auswahl eines Levels, mit Zahlen statt Meinungen

ML‑DSA gibt es in drei Parametersätzen, die den NIST‑Sicherheitskategorien 2, 3 und 5 entsprechen. Stärker bedeutet größer – sowohl Schlüssel als auch Signatur – und der vernünftige Weg, das zu entscheiden, ist, das eigene Dokument dreimal zu signieren und zu schauen:

var levels = new Dictionary<string, string>
{
    ["ML-DSA-44"] = MlDsa44Pfx,
    ["ML-DSA-65"] = MlDsa65Pfx,
    ["ML-DSA-87"] = MlDsa87Pfx
};

Das Beispiel schreibt pro Level eine signierte Kopie und erfasst jeweils die Größe, sodass der Kompromiss eine Messung und nicht eine Tabelle aus einer Spezifikation ist. Für einen einzelnen Vertrag ist der Unterschied kaum bemerkbar; für ein Archiv mit mehreren Millionen signierten Dokumenten ist es eine Kapazitätsfrage, die man vor der Standardisierung auf das höchste Level stellen sollte.

ML‑DSA‑65 ist die vernünftige Vorgabe, wenn keine Richtlinie etwas anderes vorschreibt. Profile wie CNSA 2.0 nennen explizit ML‑DSA‑87, und ML‑DSA‑44 macht nur Sinn, wenn die Größe wichtiger ist als die Sicherheitsmarge.

Verifikation benötigt nur das öffentliche Zertifikat

Die Verteilungs‑Story ändert sich nicht gegenüber RSA, was die zweite gute Nachricht ist:

var options = new DigitalVerifyOptions(certificatePath);
if (password != null)
{
    options.Password = password;
}

VerificationResult result = signature.Verify(options);

Ein Empfänger benötigt das .cer des Unterzeichners und sonst nichts. Das Ergebnis ist nur dann gültig, wenn die Signatur zum Inhalt passt und das Zertifikat per Seriennummer und Fingerabdruck übereinstimmt, sodass ein Dokument, das von einer anderen Partei signiert wurde, die Prüfung nicht besteht – was das Beispiel demonstriert, indem die Verifikation zweimal ausgeführt wird, einmal mit dem richtigen Zertifikat und einmal mit dem Zertifikat einer anderen Person.

Neben‑an‑Neben: Erwartet vs. Tatsächlich

Was ein Migrationsplan annimmt Was 26.9 tatsächlich verlangt
Code‑Änderung Abstraktionsschicht über das Signieren anderer PFX‑Pfad
API‑Oberfläche neue post‑quantum Methoden DigitalSignOptions, unverändert
Level‑Auswahl Bibliotheks‑Konfiguration welches Zertifikat geladen wird
Verifikation neue Werkzeuge für Empfänger das öffentliche .cer des Unterzeichners
Plattform‑Arbeit schlüsselbezogene Handhabung pro OS keine – die Bibliothek fällt intern zurück
Format‑Abdeckung alle Formate nur Word‑Formate, vorerst

Die letzte Zeile ist die, die die Planung einschränkt, und sie führt zum ehrlichen Teil dieses Artikels.

Was noch nicht funktioniert

Zwei Grenzen, die man kennen sollte, bevor man etwas verspricht.

Die Format‑Abdeckung beschränkt sich in 26.9 auf Word – DOCX, DOC, ODT und den Rest der Word‑Familie. PDF, Tabellenkalkulationen und Präsentationen können nicht mit ML‑DSA signiert werden. Für eine PDF‑first‑Pipeline ist dieses Release eher für Prototyping und Messungen geeignet als für eine Migration.

Die Validator‑Unterstützung ist die andere. Es gibt noch keinen standardisierten XML‑DSig‑Identifier für ML‑DSA, sodass Microsoft Word die Signatur möglicherweise nicht als gültig anzeigt, obwohl sie kryptografisch korrekt ist und über die API korrekt verifiziert wird. Das ist eine Lücke im Standard, kein Defekt, und bedeutet, dass die Verifikation im eigenen Code stattfinden muss und nicht beim Betrachter, der die Datei öffnet und das Banner prüft.

Es gibt zudem ein plattformspezifisches Detail, das keine Aktion erfordert: .NET kann ML‑DSA‑Schlüssel nicht überall lesen, z. B. unter Linux mit .NET 8. Wo das nicht möglich ist, liest GroupDocs.Signature das Zertifikat über die Word‑Engine, sodass derselbe Build auf einem Entwickler‑Laptop und in einem Linux‑Container ohne bedingten Code läuft.

Lohnt es sich jetzt, angesichts dieser Grenzen, damit zu beginnen?

Ja, aus zwei Gründen, die nichts mit dem Code zu tun haben. Die Zertifikatsbeschaffung ist langsam – öffentliche CAs rollen ML‑DSA‑Ausstellungen noch aus – sodass die organisatorische Arbeit davon profitiert, früh zu starten. Und „Können wir heute eine post‑quantum Signatur erzeugen?“ ist eine Frage, die Compliance‑Teams zunehmend stellen; mit einem signierten Dokument statt nur einem Plan zu antworten, ist den dafür benötigten Nachmittag wert.

Was das Beispiel tatsächlich beweist

Vier Methoden, nacheinander ausgeführt, wobei der Exit‑Code vom Ergebnis abhängt. Es signiert den Vertrag mit ML‑DSA‑65 und gibt das Subject des verwendeten Zertifikats aus. Es signiert denselben Vertrag auf allen drei Levels und gibt die resultierenden Größen aus. Es verifiziert die signierte Datei zweimal – einmal mit dem öffentlichen Zertifikat des Unterzeichners (Erfolg erwartet) und einmal mit dem Zertifikat eines anderen Unterzeichners (Fehlschlag erwartet). Anschließend listet es die gefundenen digitalen Signaturen im Ergebnis auf.

Die zweite Verifikation ist die, die man kopieren sollte. Eine Routine, die nur mit gültigen Eingaben gezeigt wurde, sagt nichts darüber aus, ob sie ungültige ablehnen würde – und bei Signaturen ist genau das die zentrale Frage.

Praxisbeispiel: Der 30‑Jahre‑Vertrag

Langzeit‑Archive sind der Ort, an dem das nicht mehr theoretisch bleibt. Ein heute unterschriebener Vertrag, der dreißig Jahre aufbewahrt wird, muss über alle Entwicklungen in der Kryptografie hinweg verifizierbar bleiben, und „Jetzt ernten, später entschlüsseln“ ist ein dokumentiertes Bedrohungsmodell für genau solche Materialien.

Für ein solches Archiv ist der praktische Schritt heute ein Dual‑Track‑Ansatz: RSA für die Formate beibehalten, die ML‑DSA noch nicht abdeckt, Word‑Ausgaben mit ML‑DSA‑65 oder 87 signieren und pro Dokument festhalten, welcher Algorithmus verwendet wurde, sodass ein zukünftiges Audit sie ohne Öffnen der Dateien unterscheiden kann.

Eine Sache, die im Beispiel vor dem Kopieren zu korrigieren ist

Das Repository liefert selbstsignierte ML‑DSA‑Zertifikate, sodass die Demonstration sofort funktioniert – das bedeutet vier PFX‑Dateien und ein fest codiertes Passwort in documents/. Für ein einmaliges Testzertifikat, das nur innerhalb dieses Beispiels gültig ist, ist das in Ordnung.

Es ist jedoch kein Muster, das man in das eigene Repository übernehmen sollte. Erzeugen Sie Testzertifikate zur Laufzeit, so wie das GroupDocs‑Beispiel certificate‑validity es tut, oder halten Sie sie komplett außerhalb der Versionskontrolle. Ein eingecheckter Schlüssel ist schwer zu widerrufen und überlebt meist die Demo, für die er erstellt wurde.

Fazit

Die kostenintensiven Teile einer post‑quantum Migration sind Zertifikate, Richtlinien und Validatoren. Der Code, zumindest für Word‑Dokumente in .NET, besteht aus einem anderen PFX und demselben Aufruf DigitalSignOptions. Klonen Sie das Beispiel, zeigen Sie es auf einen Ihrer eigenen Verträge, und Sie erhalten innerhalb weniger Minuten drei signierte Dateien, zwei Verifikationsergebnisse und einen Größenvergleich – eine solidere Basis für einen Migrationsplan als eine reine Schätzung.

Weitere Ressourcen