3. Version 2 Gegensignaturen
Eine Gegensignatur wird normalerweise als eine zweite Signatur definiert, die eine primäre Signatur bestätigt. Ein normales Beispiel für eine Gegensignatur ist die Signatur, die ein Notar auf ein Dokument setzt, um zu bezeugen, dass Sie das Dokument unterschrieben haben. Ein Notar fügt normalerweise einen Zeitstempel hinzu, um anzugeben, wann die Beglaubigung erfolgt; ein solcher Zeitstempel wurde jedoch für COSE noch nicht definiert. Ein Zeitstempel könnte, sobald er in einem zukünftigen Dokument definiert ist, als geschützter Header-Parameter aufgenommen werden. Das Anwenden einer Gegensignatur auf entweder die COSE_Signature- oder die COSE_Sign1-Objekte entspricht somit dieser traditionellen Definition. Dieses Dokument erweitert den Kontext einer Gegensignatur, um sie auf alle definierten Sicherheitsstrukturen anwenden zu können. Die Gegensignatur muss als separater Vorgang vom ursprünglichen Vorgang behandelt werden, selbst wenn sie vom selben Benutzer angewendet wird, wie dies in [GROUP-OSCORE] erfolgt.
COSE unterstützt zwei verschiedene Formen für Gegensignaturen. Vollständige Gegensignaturen verwenden die Struktur COSE_Countersignature, die dieselbe Struktur wie COSE_Signature aufweist. Somit können vollständige Gegensignaturen geschützte und ungeschützte Attribute, einschließlich verketteter Gegensignaturen, aufweisen. Abgekürzte Gegensignaturen verwenden die Struktur COSE_Countersignature0. Diese Struktur enthält nur den Signaturwert und sonst nichts. Die Strukturen können nicht ineinander umgewandelt werden; da die Signaturberechnung einen Parameter enthält, der die verwendete Struktur identifiziert, schlägt die Signaturvalidierung bei der umgewandelten Struktur fehl.
Die Gegensignatur der Version 2 ändert den Algorithmus zur Berechnung der Signatur gegenüber der ursprünglichen Version, die in Abschnitt 4.5 von [RFC8152] spezifiziert ist. Die neue Version enthält nun das kryptographische Material, das für alle Strukturen generiert wurde, anstatt nur für eine Teilmenge.
COSE wurde für Einheitlichkeit bei der Spezifikation der Datenstrukturen entwickelt. Ein Ergebnis davon ist, dass man für COSE das Konzept der Gegensignaturen über die bloße Idee des Signierens einer Signatur hinaus erweitern kann, um die meisten Strukturen signieren zu können, ohne eine neue Signaturschicht erstellen zu müssen. Wenn man eine Gegensignatur erstellt, muss man sich über die resultierenden Sicherheitseigenschaften im Klaren sein. Wenn dies auf einer COSE_Signature oder COSE_Sign1 erfolgt, bleibt die normale Gegensignatursemantik erhalten. Das heißt, die Gegensignatur trifft eine Aussage über die Existenz einer Signatur und, wenn sie mit einem noch zu spezifizierenden Zeitstempel verwendet wird, einen Zeitpunkt, zu dem die Signatur existiert. Wenn dies auf einem COSE_Mac oder COSE_Mac0 erfolgt, wird die Nutzlast sowie der MAC-Wert einbezogen. Wenn dies auf einem COSE_Encrypt oder COSE_Encrypt0 erfolgt, wird die Existenz der verschlüsselten Daten bestätigt. Es ist zu beachten, dass zwischen der Bestätigung der verschlüsselten Daten und der Bestätigung der unverschlüsselten Daten unterschieden wird. Wenn letzteres gewünscht ist, muss man eine Signatur auf die Daten anwenden und diese dann verschlüsseln. Es ist immer möglich, Fälle zu konstruieren, in denen die Verwendung zweier unterschiedlicher Schlüssel zu einer erfolgreichen Entschlüsselung führt, bei der die Tag-Prüfung erfolgreich ist, aber zwei völlig unterschiedliche Klartexte erzeugt werden. Diese Situation ist durch eine Gegensignatur auf den verschlüsselten Daten nicht erkennbar.
3.1. Vollständige Gegensignaturen
Die Struktur COSE_Countersignature ermöglicht denselben Satz von Funktionen wie eine COSE_Signature. Dies bedeutet, dass alle Funktionen einer Signatur mit dieser Struktur dupliziert werden. Insbesondere muss der Gegensignierer nicht mit dem Ersteller dessen verwandt sein, was gegensigniert wird, da Schlüssel- und Algorithmusidentifikation in den Gegensignaturattributen platziert werden können. Dies bedeutet auch, dass die Gegensignatur selbst gegensigniert werden kann. Dies ist eine Funktion, die von Protokollen wie Langzeitarchivierungsdiensten benötigt wird. Weitere Informationen zur Verwendung von Gegensignaturen finden Sie in der in [RFC4998] beschriebenen Beweisaufzeichnungssyntax.
Die vollständige Gegensignaturstruktur kann je nach Kontext entweder getaggt oder ungetaggt kodiert werden. Eine getaggte COSE_Countersignature-Struktur wird durch das CBOR-Tag 19 identifiziert. Die Gegensignaturstruktur ist dieselbe wie die für einen Unterzeichner auf einem signierten Objekt verwendete. Das CDDL-Fragment für vollständige Gegensignaturen ist:
COSE_Countersignature_Tagged = #6.19(COSE_Countersignature)
COSE_Countersignature = COSE_Signature
Die Details der Felder einer Gegensignatur finden sich in Abschnitt 4.1 von [RFC9052].
Ein Beispiel für eine Gegensignatur auf einer Signatur finden Sie in Anhang A.1.1. Ein Beispiel für eine Gegensignatur in einem Verschlüsselungsobjekt finden Sie in Anhang A.3.1.
Es sollte beachtet werden, dass nur ein Signaturalgorithmus mit Anhang (siehe Abschnitt 8.1 von [RFC9052]) für Gegensignaturen verwendet werden kann. Dies liegt daran, dass der Hauptteil verarbeitet werden können sollte, ohne die Gegensignatur auswerten zu müssen, und dies ist für Signaturschemata mit Nachrichtenwiederherstellung nicht möglich.
3.2. Abgekürzte Gegensignaturen
Abgekürzte Gegensignaturen unterstützen verschlüsseltes Gruppen-Messaging, bei dem die Identifizierung des Nachrichtenurhebers erforderlich ist, aber der Wunsch besteht, die Gegensignatur so klein wie möglich zu halten. Für abgekürzte Gegensignaturen sind keine geschützten Attribute im Zusammenhang mit dem Signiervorgang vorgesehen. Das heißt, die Parameter zur Berechnung oder Verifizierung der abgekürzten Gegensignatur werden durch denselben Kontext bereitgestellt, der zur Beschreibung der Verschlüsselungs-, Signatur- oder MAC-Verarbeitung verwendet wird.
Das CDDL-Fragment für die abgekürzten Gegensignaturen ist:
COSE_Countersignature0 = bstr
Der Byte-String, der den Signaturwert darstellt, wird im Attribut Countersignature0 platziert. Dieses Attribut wird dann als ungeschützter Header-Parameter kodiert.
3.3. Signier- und Verifizierungsprozess
Um eine Signatur zu erstellen, ist ein wohldefinierter Byte-String erforderlich. Die Countersign_structure wird verwendet, um die kanonische Form zu erstellen. Dieser Signier- und Verifizierungsprozess nimmt die Gegensignatur-Zielstruktur (COSE_Signature, COSE_Sign1, COSE_Sign, COSE_Mac, COSE_Mac0, COSE_Encrypt oder COSE_Encrypt0), die Unterzeichnerinformationen (COSE_Signature) und die Anwendungsdaten (externe Quelle) auf. Eine Countersign_structure ist ein CBOR-Array. Die Zielstruktur der Gegensignatur muss alle ihre kryptographischen Funktionen abgeschlossen haben, bevor die Signatur berechnet wird. Die Felder der Countersign_structure sind in der Reihenfolge:
Kontext: Ein Kontext-Textstring, der den Kontext der Signatur identifiziert. Der Kontext-Textstring ist einer der folgenden:
-
"CounterSignature" für Gegensignaturen unter Verwendung der COSE_Countersignature-Struktur, wenn other_fields fehlt.
-
"CounterSignature0" für Gegensignaturen unter Verwendung der COSE_Countersignature0-Struktur, wenn other_fields fehlt.
-
"CounterSignatureV2" für Gegensignaturen unter Verwendung der COSE_Countersignature-Struktur, wenn other_fields vorhanden ist.
-
"CounterSignature0V2" für Gegensignaturen unter Verwendung der COSE_Countersignature0-Struktur, wenn other_fields vorhanden ist.
body_protected: Die serialisierten geschützten Attribute aus der Zielstruktur, kodiert in einem bstr-Typ. Wenn keine geschützten Attribute vorhanden sind, wird ein Byte-String der Länge Null verwendet.
sign_protected: Die serialisierten geschützten Attribute aus der Unterzeichnerstruktur, kodiert in einem bstr-Typ. Wenn keine geschützten Attribute vorhanden sind, wird ein Byte-String der Länge Null verwendet. Dieses Feld wird für das Countersignature0V2-Attribut weggelassen.
external_aad: Die extern bereitgestellten zusätzlichen authentifizierten Daten (AAD) von der Anwendung, kodiert in einem bstr-Typ. Wenn dieses Feld nicht angegeben wird, ist der Standardwert ein Byte-String der Länge Null. (Siehe Abschnitt 4.4 von [RFC9052] für Anwendungsrichtlinien zum Erstellen dieses Feldes.)
payload: Die zu signierende Nutzlast, kodiert in einem bstr-Typ. Die Nutzlast wird hier unabhängig davon platziert, wie sie transportiert wird.
other_fields: Weggelassen, wenn nur zwei bstr-Felder in der Zielstruktur vorhanden sind. Dieses Feld ist ein Array aller bstr-Felder nach dem zweiten. Als Beispiel wäre dies ein Array aus einem Element für die COSE_Sign1-Struktur, das den Signaturwert enthält.
Das CDDL-Fragment, das den obigen Text beschreibt, ist:
Countersign_structure = [
context : "CounterSignature" / "CounterSignature0" /
"CounterSignatureV2" / "CounterSignature0V2" /,
body_protected : empty_or_serialized_map,
? sign_protected : empty_or_serialized_map,
external_aad : bstr,
payload : bstr,
? other_fields : [+ bstr ]
]
So berechnen Sie eine Gegensignatur:
-
Erstellen Sie eine Countersign_structure und füllen Sie sie mit den entsprechenden Feldern.
-
Erstellen Sie den Wert ToBeSigned, indem Sie die Countersign_structure in einen Byte-String kodieren, unter Verwendung der in Abschnitt 4 beschriebenen Kodierung.
-
Rufen Sie den Signaturerstellungsalgorithmus auf, indem Sie K (den Schlüssel zum Signieren), alg (den Algorithmus zum Signieren) und ToBeSigned (den zu signierenden Wert) übergeben.
-
Platzieren Sie den resultierenden Signaturwert an der richtigen Stelle. Dies ist das Feld "signature" der COSE_Countersignature-Struktur für vollständige Gegensignaturen (siehe Abschnitt 3.1). Dies ist der Wert des Countersignature0-Attributs für abgekürzte Gegensignaturen (siehe Abschnitt 3.2).
Die Schritte zum Verifizieren einer Gegensignatur:
-
Erstellen Sie eine Countersign_structure und füllen Sie sie mit den entsprechenden Feldern.
-
Erstellen Sie den Wert ToBeSigned, indem Sie die Countersign_structure in einen Byte-String kodieren, unter Verwendung der in Abschnitt 4 beschriebenen Kodierung.
-
Rufen Sie den Signaturverifizierungsalgorithmus auf, indem Sie K (den Schlüssel zum Verifizieren), alg (den zum Signieren verwendeten Algorithmus), ToBeSigned (den zu signierenden Wert) und sig (die zu verifizierende Signatur) übergeben.
Zusätzlich zur Durchführung der Signaturverifizierung führt die Anwendung die entsprechenden Überprüfungen durch, um sicherzustellen, dass der Schlüssel korrekt mit der signierenden Identität gepaart ist und dass die signierende Identität autorisiert ist, bevor Aktionen ausgeführt werden.