Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Hintergrund und Theorie
Im Datenschutzsystem bedeutet ein "Schlüssel" ein Objekt, das authentifizierte Verschlüsselungsdienste bereitstellen kann. Jeder Schlüssel wird durch eine eindeutige ID (eine GUID) identifiziert und trägt algorithmische Informationen und entropisches Material. Es ist beabsichtigt, dass jeder Schlüssel eine eindeutige Entropie trägt, aber das System kann dies nicht erzwingen, und wir müssen auch Entwickler berücksichtigen, die den Schlüsselring manuell ändern können, indem die algorithmischen Informationen eines vorhandenen Schlüssels im Schlüsselring geändert werden. Um unsere Sicherheitsanforderungen zu erreichen, hat das Datenschutzsystem ein Konzept der kryptografischen Flexibilität, das eine sichere Verwendung eines einzelnen entropischen Werts über mehrere kryptografische Algorithmen hinweg ermöglicht.
Die meisten Systeme, die kryptografische Flexibilität unterstützen, enthalten einige identifizierende Informationen zum Algorithmus innerhalb der Nutzlast. Das OID des Algorithmus ist in der Regel ein guter Kandidat dafür. Ein Problem, auf das wir gestoßen sind, besteht darin, dass es mehrere Möglichkeiten gibt, denselben Algorithmus anzugeben: "AES" (CNG) und die verwalteten Klassen Aes, AesManaged, AesCryptoServiceProvider, AesCng und RijndaelManaged (unter bestimmten Parametern) sind eigentlich dasselbe, und wir müssen eine Zuordnung aller dieser Klassen zur richtigen OID beibehalten. Wenn ein Entwickler einen benutzerdefinierten Algorithmus (oder sogar eine andere Implementierung von AES!) bereitstellen wollte, müssten sie uns das OID mitteilen. Dieser zusätzliche Registrierungsschritt macht die Systemkonfiguration besonders schmerzhaft.
Indem wir einen Schritt zurücktraten, haben wir entschieden, dass wir uns dem Problem aus der falschen Richtung näherten. Ein OID sagt Ihnen, was der Algorithmus ist, aber wir kümmern uns nicht darum. Wenn wir einen einzelnen entropischen Wert sicher in zwei verschiedenen Algorithmen verwenden müssen, ist es nicht notwendig, dass wir wissen, was die Algorithmen tatsächlich sind. Was wir eigentlich interessieren, ist, wie sie sich verhalten. Jeder anständige symmetrische Blockchiffrealgorithmus ist auch ein starker Pseudorandom-Permutationsalgorithmus (PRP): Die Eingaben (Schlüssel, Verkettungsmodus, IV, Klartext) und die Chiffreausgabe unterscheiden sich mit überwältigender Wahrscheinlichkeit von jedem anderen symmetrischen Blockchiffrealalgorithmus, der dieselben Eingaben hat. Ebenso ist jede anständige Schlüssel-Hash-Funktion auch eine starke pseudorandom-Funktion (PRF), und wenn ein fester Eingabesatz gegeben ist, ist seine Ausgabe überwiegend von der jeder anderen Schlüssel-Hash-Funktion verschieden.
Wir verwenden dieses Konzept von starken PRPs und PRFs, um einen Kontextheader zu erstellen. Dieser Kontextheader fungiert im Wesentlichen als stabiler Fingerabdruck über die Algorithmen, die für einen bestimmten Vorgang verwendet werden, und bietet die vom Datenschutzsystem benötigte kryptografische Flexibilität. Dieser Header ist reproduzierbar und wird später als Teil des Unterschlüsselableitungsprozesses verwendet. Es gibt zwei verschiedene Möglichkeiten, um den Kontextheader abhängig von den Betriebsmodi der zugrunde liegenden Algorithmen zu erstellen.
CBC-Modus-Verschlüsselung + HMAC-Authentifizierung
Der Kontextheader besteht aus den folgenden Komponenten:
[16 Bits] Der Wert 00 00, ein Marker, der "CBC-Verschlüsselung + HMAC-Authentifizierung" bedeutet.
[32 Bits] Die Schlüssellänge (in Bytes, Big-Endian) des symmetrischen Blockchiffrealgorithmus.
[32 Bits] Die Blockgröße (in Bytes, Big-Endian) des symmetrischen Blockchiffrealgorithmus.
[32 Bits] Die Schlüssellänge (in Bytes, Big-Endian) des HMAC-Algorithmus. (Derzeit entspricht die Schlüsselgröße immer der Digestgröße.)
[32 Bits] Die Digestgröße (in Bytes, Big-Endian) des HMAC-Algorithmus.
EncCBC(K_E, IV, "")ist die Ausgabe des symmetrischen Blockchiffrealgorithmus mit einer leeren Eingabezeichenfolge und wobei IV ein Nullvektor ist. Der Bau vonK_Ewird unten beschrieben.MAC(K_H, ""), ist die Ausgabe des HMAC-Algorithmus bei einer leeren Zeichenfolgeneingabe. Der Bau vonK_Hwird unten beschrieben.
Im Idealfall könnten wir Nullvektoren für K_E und K_H übergeben. Wir möchten jedoch die Situation vermeiden, in der der zugrunde liegende Algorithmus vor dem Ausführen von Vorgängen (insbesondere DES und 3DES) auf das Vorhandensein schwacher Schlüssel überprüft, was die Verwendung eines einfachen oder wiederholbaren Musters wie einem All-Zero-Vektor verhindert.
Stattdessen verwenden wir die NIST SP800-108 KDF im Leistungsindikatormodus (siehe NIST SP800-108, Sec. 5.1) mit einem Schlüssel, einer Bezeichnung und einem Kontext der Länge null und HMACSHA512 als zugrunde liegende PRF. Wir leiten | K_E | + | K_H | Bytes der Ausgabe ab und dekompilieren dann das Ergebnis in K_E und K_H selbst. Mathematisch wird dies wie folgt dargestellt.
( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")
Beispiel: AES-192-CBC + HMACSHA256
Betrachten Sie beispielsweise den Fall, in dem der symmetrische Blockchiffrealgorithmus AES-192-CBC ist und der Validierungsalgorithmus HMACSHA256 ist. Das System generiert den Kontextheader mithilfe der folgenden Schritte.
Lassen Sie zunächst ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), wobei | K_E | = 192 bits und | K_H | = 256 bits gemäß der angegebenen Algorithmen. Dies führt zu K_E = 5BB6..21DD und K_H = A04A..00A9 im folgenden Beispiel:
5B B6 C9 83 13 78 22 1D 8E 10 73 CA CF 65 8E B0
61 62 42 71 CB 83 21 DD A0 4A 05 00 5B AB C0 A2
49 6F A5 61 E3 E2 49 87 AA 63 55 CD 74 0A DA C4
B7 92 3D BF 59 90 00 A9
Als Nächstes berechnen Sie Enc_CBC (K_E, IV, "") für AES-192-CBC, gegeben IV = 0* und K_E wie oben.
result := F474B1872B3B53E4721DE19C0841DB6F
Berechnen Sie als Nächstes MAC(K_H, "") für HMACSHA256 mit K_H wie oben angegeben.
result := D4791184B996092EE1202F36E8608FA8FBD98ABDFF5402F264B1D7211536220C
Dadurch wird die vollständige Kontextkopfzeile unten erzeugt:
00 00 00 00 00 18 00 00 00 10 00 00 00 20 00 00
00 20 F4 74 B1 87 2B 3B 53 E4 72 1D E1 9C 08 41
DB 6F D4 79 11 84 B9 96 09 2E E1 20 2F 36 E8 60
8F A8 FB D9 8A BD FF 54 02 F2 64 B1 D7 21 15 36
22 0C
Dieser Kontextheader ist der Fingerabdruck des authentifizierten Verschlüsselungsalgorithmuspaars (AES-192-CBC-Verschlüsselung + HMACSHA256 Validierung). Die Komponenten, wie oben beschrieben, sind:
die Markierung
(00 00)Die Schlüssellänge der Blockchiffre
(00 00 00 18)Die Blockchiffre-Blockgröße
(00 00 00 10)Die Länge des HMAC-Schlüssels
(00 00 00 20)Die Größe des HMAC-Digests
(00 00 00 20)die Blockchiffre-PRP-Ausgabe
(F4 74 - DB 6F)unddie HMAC PRF-Ausgabe
(D4 79 - end).
Hinweis
Der CBC-Modus-Verschlüsselungs- und HMAC-Authentifizierungskontextheader wird auf die gleiche Weise erstellt, unabhängig davon, ob die Algorithmenimplementierungen von Windows CNG oder von verwalteten SymmetricAlgorithm- und KeyedHashAlgorithm-Typen bereitgestellt werden. Dadurch können Anwendungen, die auf verschiedenen Betriebssystemen ausgeführt werden, zuverlässig denselben Kontextheader erzeugen, obwohl sich die Implementierungen der Algorithmen zwischen OSes unterscheiden. (In der Praxis muss der KeyedHashAlgorithm kein ordnungsgemäßer HMAC sein. Dabei kann es sich um einen beliebigen Hashalgorithmustyp mit Schlüsseln sein.)
Beispiel: 3DES-192-CBC + HMACSHA1
Lassen Sie zunächst ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), wo | K_E | = 192 bits und | K_H | = 160 bits gemäß den angegebenen Algorithmen. Dies führt zu K_E = A219..E2BB und K_H = DC4A..B464 im folgenden Beispiel:
A2 19 60 2F 83 A9 13 EA B0 61 3A 39 B8 A6 7E 22
61 D9 F8 6C 10 51 E2 BB DC 4A 00 D7 03 A2 48 3E
D1 F7 5A 34 EB 28 3E D7 D4 67 B4 64
Als Nächstes berechnen Sie Enc_CBC (K_E, IV, "") für 3DES-192-CBC, gegeben IV = 0* und K_E, wie oben angegeben.
result := ABB100F81E53E10E
Berechnen Sie als Nächstes MAC(K_H, "") für HMACSHA1 unter Verwendung von K_H, wie oben angegeben.
result := 76EB189B35CF03461DDF877CD9F4B1B4D63A7555
Dies erzeugt den vollständigen Kontextheader, der ein Fingerabdruck des authentifizierten Verschlüsselungsalgorithmuspaars ist (3DES-192-CBC-Verschlüsselung + HMACSHA1 Validierung), siehe unten:
00 00 00 00 00 18 00 00 00 08 00 00 00 14 00 00
00 14 AB B1 00 F8 1E 53 E1 0E 76 EB 18 9B 35 CF
03 46 1D DF 87 7C D9 F4 B1 B4 D6 3A 75 55
Die Komponenten werden wie folgt aufgeteilt:
die Markierung
(00 00)Die Schlüssellänge der Blockchiffre
(00 00 00 18)Die Blockchiffre-Blockgröße
(00 00 00 08)Die Länge des HMAC-Schlüssels
(00 00 00 14)die Größe des HMAC-Digests
(00 00 00 14)die Blockchiffre-PRP-Ausgabe
(AB B1 - E1 0E)unddie HMAC PRF-Ausgabe
(76 EB - end).
Galois/Counter Mode Verschlüsselung + Authentifizierung
Der Kontextheader besteht aus den folgenden Komponenten:
[16 Bits] Der Wert 00 01, ein Marker, der "GCM-Verschlüsselung + Authentifizierung" bedeutet.
[32 Bits] Die Schlüssellänge (in Bytes, Big-Endian) des symmetrischen Blockchiffrealgorithmus.
[32 Bits] Die Nonce-Größe (in Bytes, Big-Endian), die bei authentifizierten Verschlüsselungsvorgängen verwendet wird. (Für unser System ist dies bei Nonce-Größe = 96 Bits festgelegt.)
[32 Bits] Die Blockgröße (in Bytes, Big-Endian) des symmetrischen Blockchiffrealgorithmus. (Für GCM ist dies bei blockgröße = 128 Bits festgelegt.)
[32 Bits] Die Größe des Authentifizierungstags (in Bytes, Big-Endian), die von der authentifizierten Verschlüsselungsfunktion erzeugt wird. (Für unser System ist dies mit der Taggröße = 128 Bits festgelegt.)
[128 Bits] Das Tag von
Enc_GCM (K_E, nonce, ""), das die Ausgabe des symmetrischen Blockchiffrealgorithmus mit einer leeren Zeichenfolgeneingabe und wobei Nonce ein 96-Bit-All-Zero-Vektor ist.
K_E wird mit demselben Mechanismus wie im CBC-Verschlüsselungs- und HMAC-Authentifizierungsszenario abgeleitet. Da hier jedoch kein K_H im Einsatz ist, haben wir im Wesentlichen | K_H | = 0, und der Algorithmus vereinfacht sich auf die folgende Form.
K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")
Beispiel: AES-256-GCM
Lassen Sie zuerst K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), wo | K_E | = 256 bits.
K_E := 22BC6F1B171C08C4AE2F27444AF8FC8B3087A90006CAEA91FDCFB47C1B8733B8
Als Nächstes berechnen Sie den Authentifizierungstag von Enc_GCM (K_E, nonce, "") für AES-256-GCM mit nonce = 096 und K_E, wie oben angegeben.
result := E7DCCE66DF855A323A6BB7BD7A59BE45
Dadurch wird die vollständige Kontextkopfzeile unten erzeugt:
00 01 00 00 00 20 00 00 00 0C 00 00 00 10 00 00
00 10 E7 DC CE 66 DF 85 5A 32 3A 6B B7 BD 7A 59
BE 45
Die Komponenten werden wie folgt aufgeteilt:
die Markierung
(00 01)Die Länge des Blockchiffre-Schlüssels
(00 00 00 20)die Nonce-Größe
(00 00 00 0C)Die Blockchiffre-Blockgröße
(00 00 00 10)Die Größe des Authentifizierungstags
(00 00 00 10)unddas Authentifizierungsetikett aus der Ausführung der Blockchiffre
(E7 DC - end).
ASP.NET Core