Crypto Cheat Sheet
Transcrição
Crypto Cheat Sheet
Crypto Cheat Sheet Kryptographie: Best Practices Manu Carus http://www.ethical-hacking.de/ mailto:[email protected] INHALTSVERZEICHNIS 1 KRYPTOGRAPHIE 5 1.1 KRYPTOGRAPHISCHE ZIELE 1.2 BEST PRACTICES 1.2.1 KRYPTOGRAPHISCHE AGILITÄT 1.3 WORST PRACTICES 1.3.1 SECURITY BY OBSCURITY 1.3.2 AD-‐HOC-‐ALGORITHMEN 5 7 7 8 8 8 2 ZUFALLSZAHLEN 9 2.1 UNTERSTÜTZUNG IN LIBRARIES UND FRAMEWORKS 2.1.1 OPENSSL 2.1.2 JAVA CRYPTOGRAPHY ARCHITECTURE 2.1.3 .NET 2.1.4 CRYPTOAPI / CAPICOM 2.2 BEST PRACTICES 2.2.1 KRYPTOGRAPHISCH SICHERE GUIDS 2.3 RULES OF THUMB 2.3.1 AUFWAND BEI DER BERECHNUNG KRYPTOGRAPHISCH SICHERER ZUFALLSZAHLEN 9 9 9 9 9 10 10 10 10 3 HASHALGORITHMEN 11 3.1 ANFORDERUNGEN AN EINEN SICHEREN HASH-‐ALGORITHMUS 3.2 EINSATZGEBIETE 3.2.1 PRÜFSUMMEN 3.2.2 DIGITALE SIGNATUREN 3.2.3 VERGLEICH GROßER EINGABEN 3.3 SICHERE HASHVERFAHREN 3.4 UNTERSTÜTZUNG IN LIBRARIES UND FRAMEWORKS 3.4.1 OPENSSL 3.4.2 JAVA CRYPTOGRAPHY ARCHITECTURE 3.4.3 .NET 3.4.4 CRYPTOAPI / CAPICOM 3.5 BEST PRACTICES 3.5.1 SHA-‐256 3.5.2 HASHWERTE DER LÄNGE 256 BIT UND GRÖßER 3.5.3 HASHING ANSTATT VERSCHLÜSSELUNG 3.5.4 SALTED HASHING ANSTATT HASHING 3.5.5 VERGLEICH LANGER EINGABEN 3.5.6 INTEGRITÄTSPRÜFUNG 3.5.7 HASHWERTE VERSCHLÜSSELT ÜBERTRAGEN 3.5.8 DIGITALE SIGNATUR STATT HASHING 3.6 WORST PRACTICES 3.6.1 MD5 3.6.2 SHA-‐1 3.7 RULES OF THUMB 3.7.1 KOLLISIONSFREIHEIT 12 12 12 12 12 13 13 13 13 13 13 14 14 14 14 14 14 15 15 15 15 15 15 16 16 4 SALTED HASHING 17 5 MESSAGE AUTHENTICATION CODES 19 5.1 SICHERE MAC-‐VERFAHREN 5.2 UNTERSTÜTZUNG IN LIBRARIES UND FRAMEWORKS 5.2.1 OPENSSL 5.2.2 JAVA CRYPTOGRAPHY ARCHITECTURE 5.2.3 .NET 5.2.4 CRYPTOAPI / CAPICOM 5.3 BEST PRACTICES 5.3.1 HMACSHA256 UND AES-‐CMAC-‐256 5.3.2 VERWENDUNG LANGER SCHLÜSSEL 5.3.3 DIGITALE SIGNATUREN 19 20 20 20 20 20 21 21 21 21 6 SYMMETRISCHE VERSCHLÜSSELUNG 22 6.1 SCHLÜSSELAUSTAUSCH 6.2 SICHERE SYMMETRISCHE ALGORITHMEN 6.3 UNTERSTÜTZUNG IN LIBRARIES UND FRAMEWORKS 6.3.1 OPENSSL 6.3.2 JAVA CRYPTOGRAPHY ARCHITECTURE 6.3.3 .NET 6.3.4 CRYPTOAPI / CAPICOM 6.4 BEST PRACTICES 6.4.1 AES-‐256 6.4.2 SCHLÜSSEL DER LÄNGE 128 BIT UND GRÖßER 6.4.3 SCHLÜSSEL DER LÄNGE 256 BIT 6.4.4 SSL ANSTATT SYMMETRISCHER VERSCHLÜSSELUNG 6.4.5 HYBRIDE VERSCHLÜSSELUNG STATT SYMMETRISCHER VERSCHLÜSSELUNG 6.4.6 SCHLÜSSELGENERIERUNG 6.4.7 INITIALISIERUNGSVEKTOR 6.4.8 CIPHER BLOCK CHAINING (CBC) 6.4.9 PKCS #7 PADDING 6.4.10 SCHLÜSSEL VON EINEM PASSWORT ABLEITEN 6.4.11 STARKE PASSWÖRTER 6.5 WORST PRACTICES 6.5.1 DES 6.5.2 ELECTRONIC CODE BOOK (ECB) 6.5.3 DATEN AUF EINER DURCHGEHEND ABGESICHERTEN LEITUNG ZWEIFACH VERSCHLÜSSELN 6.5.4 VERSCHLÜSSELTE DATEN KOMPRIMIEREN 6.6 RULES OF THUMB 6.6.1 TWOFISH STATT BLOWFISH 6.6.2 SCHLÜSSELSTÄRKE VON TRIPLE DES 6.6.3 ENCODING SYNCHRONISIEREN 6.6.4 LAUFZEITVORTEIL VON AES 23 23 24 24 24 24 25 25 25 25 25 25 25 25 26 26 26 27 27 28 28 28 28 28 29 29 29 29 29 7 ASYMMETRISCHE VERSCHLÜSSELUNG 30 7.1 GEHEIMHALTUNG 7.2 SICHERE ASYMMETRISCHE VERSCHLÜSSELUNGSALGORITHMEN 7.3 UNTERSTÜTZUNG IN LIBRARIES UND FRAMEWORKS 7.3.1 OPENSSL 7.3.2 JAVA CRYPTOGRAPHY ARCHITECTURE 7.3.3 .NET 33 34 34 34 34 34 7.3.4 CRYPTOAPI / CAPICOM 7.4 BEST PRACTICES 7.4.1 RSA-‐2048 7.4.2 HYBRIDE VERSCHLÜSSELUNG 7.4.3 VERSAND AN MEHRERE EMPFÄNGER 7.5 WORST PRACTICES 7.5.1 RSA-‐1024 7.5.2 INHALTE ASYMMETRISCH VERSCHLÜSSELN 34 35 35 35 35 36 36 36 8 HYBRIDE VERSCHLÜSSELUNG 37 8.1 ERREICHEN DER KRYPTOGRAPHISCHEN ZIELE 8.2 UNTERSTÜTZUNG IN LIBRARIES UND FRAMEWORKS 8.2.1 OPENSSL 8.3 BEST PRACTICES 8.3.1 SCHNELL UND SICHER 39 39 39 40 40 9 DIGITALE SIGNATUR 41 9.1 SICHERE SIGNATURALGORITHMEN 9.2 UNTERSTÜTZUNG IN LIBRARIES UND FRAMEWORKS 9.2.1 OPENSSL 9.2.2 JAVA CRYPTOGRAPHY ARCHITECTURE 9.2.3 .NET 9.2.4 CRYPTOAPI / CAPICOM 9.3 BEST PRACTICES 9.3.1 DSA STATT RSA 9.3.2 SIGNATURVERFAHREN MIT HASHWERTEN DER LÄNGE 160 BIT UND GRÖßER 9.3.3 PROTOKOLL ÜBER ALLE SIGNIERTEN DOKUMENTE FÜHREN 42 43 43 43 43 44 44 44 44 44 10 SCHLÜSSELAUSTAUSCHVERFAHREN 45 10.1 UNTERSTÜTZUNG IN LIBRARIES UND FRAMEWORKS 10.1.1 OPENSSL 10.1.2 JAVA CRYPTOGRAPHY ARCHITECTURE 10.1.3 .NET 10.1.4 CRYPTOAPI / CAPICOM 10.2 BEST PRACTICES 10.2.1 DIFFIE-‐HELLMAN NUR IN VERBINDUNG MIT EINER GEGENSEITIGEN AUTHENTISIERUNG 10.3 RULES OF THUMB 10.3.1 AUFWAND BEI DER BERECHNUNG DER DIFFIE-‐HELLMAN-‐PARAMETER 46 46 46 46 46 46 46 47 47 11 IN-‐MEMORY-‐VERSCHLÜSSELUNG 47 12 SALVATORISCHE KLAUSELN 48 12.1 KRYPTOGRAPHISCH SCHWACHE ALGORITHMEN 12.2 GEBOT DER VORSICHT 48 48 13 ABKÜRZUNGSVERZEICHNIS 49 1 Kryptographie Definitionen Die Kryptographie ist die Wissenschaft der Verschlüsselung von Information. Dem steht die Kryptoanalyse entgegen, mit dem Ziel, bisher als sicher eingeschätzte Verfahren zu analysieren und zu brechen. Beide Wissenschaften sind Teilgebiete der Kryptologie. 1.1 Kryptographische Ziele Die moderne Kryptographie definiert vier Hauptziele zum Schutz von vertraulicher Information: Vertraulichkeit (Secrecy) „keeping information secret“ Zu schützende Information muss geheim bleiben. Nur ausdrücklich berechtigte Personen dürfen in der Lage sein, vertrauliche Nachrichten zu lesen oder Informationen über deren Inhalt zu erlangen. Integrität (Integrity) „knowing that information hasn’t been tampered with“ Der Empfänger einer Nachricht muss in der Lage sein festzustellen, ob die Nachricht nach ihrer Erzeugung und vor ihrem Empfang modifiziert wurde. Authentizität (Authentication) „knowing the origin and destination of information“ Urheber und Empfänger einer Nachricht müssen beide eindeutig identifizierbar sein. Nichtabstreitbarkeit (Non-Repudiation) „knowing that information, once sent, cannot be retracted or denied“. Der Urheber einer Nachricht darf nicht in der Lage sein, seine Urheberschaft zu bestreiten. Die Urheberschaft muss sich gegenüber Dritten nachweisen lassen. Abbildung: Kryptographische Ziele Anforderung Eine „sichere“ Applikation muss diese vier kryptographischen Ziele erreichen! Durch den Einsatz der nachfolgend vorgestellten Verfahren können diese Ziele erreicht werden. Allerdings kann der vollständige Schutz vertraulicher Daten hierdurch alleine nicht garantiert werden. Vielmehr lassen die jeweils eingesetzten Technologien, beteiligten Personen und Systeme sowie die angewendeten Prozesse weitere Angriffsvektoren offen. Beispiel: Man-in-the-Middle-Attack, ReplayAngriffe, Injection Flaws. 1.2 Best Practices 1.2.1 Kryptographische Agilität Da Kryptoanalysten bekannte und neue Kryptoalgorithmen fortlaufend auf potentielle Schwachstellen abklopfen, kann die Situation eintreten, dass ein bisher als sicher eingestufter Kryptoalgorithmus schnellstmöglich ausgetauscht werden muss. So wurde bspw. im Dezember 2008 eine Kollisionsschwäche in dem Hashverfahren MD5 nachgewiesen. In einem solchen Fall sollte eine Applikation schnell und flexibel auf einen stärkeren Kryptoalgorithmus umstellen können, möglichst ohne dass der zugrunde liegende Quellcode erneut übersetzt und ausgeliefert werden muss. Beispiel (C#) string cipherName = ConfigurationManager.AppSettings["Cipher"]; // AES-256 SymmetricAlgorithm cipher = SymmetricAlgorithm.Create(cipherName); anstatt DESCryptoServiceProvider cipher = new DESCryptoServiceProvider(); Die anzuwendenden Kryptoalgorithmen können bspw. in einer Konfigurationsdatei benannt werden. Letztere muss gegen unauthorisierte Modifikationen abgesichert werden, bspw. durch digitale Signatur oder Verifikation eines HMACs, denn ansonsten könnte ein Angreifer einen sicheren Kryptoalgorithmus gegen einen schwachen austauschen (bspw. AES-256 ð DES). 1.3 Worst Practices 1.3.1 Security by Obscurity Geheimnisse dürfen nicht „verschleiert“ werden, sondern müssen geheim bleiben. Aus diesem Grund dürfen Passwörter, Schlüssel oder sonstige kryptographisch sensible Informationen nicht im Source Code oder an anderen grundsätzlich zugänglichen Stellen „versteckt“ werden. Es ist davon auszugehen, dass vermeintliche Verstecke immer gefunden werden, insbesondere von Dritten, die keine Kenntnis über solche Verstecke haben dürfen. Beispiel Binär-Code kann dekompiliert werden; ein Angreifer kann auf diese Weise nicht nur „geheime“ Strings finden, sondern die gesamte Verarbeitungslogik einer Anwendung analysieren. Daher dürfen Geheimnisse niemals hart kodiert werden. Verschleierungstaktiken wie die Speicherung von ByteArrays statt Zeichenketten im Source-Code machen die „Geheimnisse“ nicht schwerer lesbar. Beispiel „Geheime“ Debug-Schalter in einer Release-Version sprechen sich herum; musste der Support bei der telefonischen Bearbeitung eines Problemfalls ein einziges Mal einen Anwender anweisen, einen „geheimen“ Schalter umzulegen, ist das „Geheimnis“ öffentlich! Desweiteren ist davon auszugehen, dass ein Angreifer umfassende Kenntnis über die eingesetzten kryptographischen Algorithmen und deren Schlüssellängen und Blocklängen hat, sowie über Techniken zur Erzeugung von Zufallszahlen, Tickets und auf Basis von Zufallszahlen generierten Schlüsseln. 1.3.2 Ad-hoc-Algorithmen Selbst erdachte Algorithmen für die Verschlüsselung, das Hashing und die Erzeugung von Zufallszahlen o.ä. dürfen nicht verwendet werden: ihnen fehlt die kryptographische Analyse durch hochgeschulte Kryptoanalysten! Fragestellungen wie Schlüssellängen, Verkettungsmodi und die interne Verarbeitung der Daten durch den Algorithmus erfordern eine gründliche Analyse auf mögliche Schwachstellen. Bewährte Algorithmen wie bspw. AES verschlüsseln durch Expansion, Substitution, Verschiebung, Falten und Spiegeln in mehreren Runden, wobei die Anzahl der Runden von Schlüssel- und Blocklänge abhängt. 2 Zufallszahlen Ein finiter Algorithmus lässt sich in Form eines endlichen Automaten darstellen. Gleiche Eingaben erzeugen gleiche Ausgaben. Herkömmlich konstruierte „Zufallszahlen“ basieren daher auf deterministischen Parametern wie der Systemzeit, der MAC-Adresse, des CPU Instruction Pointers etc. Sie sind daher nicht wirklich zufällig, sondern in gewisser Weise vorhersehbar. Kryptographische Algorithmen erfordern hingegen echte Zufallszahlen: Schlüssel, Initialisierungsvektoren und Salts dürfen unter keinen Umständen vorhersagbar sein. Daher sind im Kontext einer Verschlüsselung spezielle Algorithmen für die Erzeugung kryptographisch sicherer Zufallszahlen zu verwenden. 2.1 Unterstützung in Libraries und Frameworks 2.1.1 OpenSSL openssl rand 2.1.2 Java Cryptography Architecture java.security.SecureRandom 2.1.3 (algorithm ∈ {SHA1PRNG}) .NET System.Security.Cryptography.RNGCryptoServiceProvider 2.1.4 CryptoAPI / CAPICOM CryptGenKey() CryptGenRandom() 2.2 Best Practices 2.2.1 Kryptographisch sichere GUIDs Globally Unique Identifiers (GUIDs) sind global eindeutige 128 bit-Zahlen (16 Bytes), die häufig als Session-ID o.ä. eingesetzt werden. Von einer GUID ist nicht bekannt, ob sie kryptographisch sicher ist! Daher dürfen die StandardAlgorithmen zur Erzeugung einer GUID nicht in einem kryptographischen Kontext eingesetzt werden: C++: GUID .NET: System.Guid Stattdessen muss ein Byte-Array der Länge 16 mit kryptographisch sicheren Zufallszahlen erzeugt und in das Format einer GUID überführt werden. Beispiel (C++) ... array<Byte>^ randomNumber = gcnew array<Byte>(16); RNGCryptoServiceProvider^ cryptoProvider = gcnew RNGCryptoServiceProvider(); cryptoProvider->GetBytes(randomNumber); ... Beispiel (C#) ... byte[] randomBytes = new byte[16]; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); rng.GetBytes(randomBytes); Guid guid = new Guid(randomBytes); ... Beispiel (Java) Die Ausnahme bildet Java mit der Klasse java.util.UUID, die bereits kryptographisch sichere Zufallszahlen erzeugt: ... UUID uuid = java.util.UUID.randomUUID(); ... 2.3 Rules of Thumb 2.3.1 Aufwand bei der Berechnung kryptographisch sicherer Zufallszahlen Die Berechnung kryptographisch sicherer Zufallszahlen ist ca. 10 Mal aufwändiger als die Berechnung gewöhnlicher Zufallszahlen. 3 Hashalgorithmen „to hash“ (engl.) = etwas „zerhacken“ (dt.) Ein Hash-Algorithmus h ist eine Funktion, die eine Zeichenkette z* beliebiger Länge auf einen möglichst eindeutigen, vergleichsweise kleinen Zahlenwert w fester Länge abbildet: * k h: Z → {0,1} mit Z := { z | z ∈ Unicode } und k>0 fest Abbildung: Hashing Ein Hashwert repräsentiert seine Eingabe in Form eines einfach handhabbaren, kurzen Zahlenwerts und wird daher auch als „Fingerprint“ bezeichnet. 3.1 Anforderungen an einen sicheren Hash-Algorithmus Kryptographisch sichere Hash-Algorithmen müssen die folgenden Anforderungen erfüllen: • Zu einem gegebenem Hashwert h(z*) = w muss es praktisch unmöglich sein, den Eingabewert z* zu finden (Einwegfunktion). • Kollisionen dürfen praktisch nicht auftreten, d.h. z* ≠ z'* ð h(z*) ≠ h(z'*). • Avalanche-Effekt: Die Hashfunktion soll auf jede noch so kleine Änderung der Eingabe möglichst sensitiv reagieren (kleine Änderung, große Wirkung). Bspw. sollte das Hinzufügen eines einzelnen Zeichens in der Eingabe eine über 30%-ige Änderung der Bits in dem resultierenden Hashwert bewirken. 3.2 Einsatzgebiete 3.2.1 Prüfsummen Berechnet der Empfänger den Hashwert einer Datei und vergleicht diese Prüfsumme mit dem vom Absender veröffentlichten Hashwert, kann die Integrität der Datei sichergestellt werden. 3.2.2 Digitale Signaturen Eine digitale Signatur ist der mit dem privaten Schlüssel seines Besitzers verschlüsselte Hashwert einer Information. 3.2.3 Vergleich großer Eingaben Anstatt zwei lange Eingaben byteweise zu vergleichen, können effizienter die Hashwerte der beiden Eingaben miteinander verglichen werden. 3.3 Sichere Hashverfahren Algorithmus SHA-256 Secure Hash Algorithm SHA-384 SHA-512 RIPEMD-160 RACE Integrity Primitives Evaluation Message Digest Hashwert 256 bit 32 Bytes 384 bit 48 Bytes 512 bit 64 Bytes 160 bit 20 Bytes Stand: 12/2012 3.4 Unterstützung in Libraries und Frameworks 3.4.1 OpenSSL openssl dgst –alg (alg ∈ {sha256, sha384, sha512, ripemd160}) 3.4.2 Java Cryptography Architecture java.security.MessageDigest 3.4.3 (algorithm ∈ {SHA-256, SHA-384, SHA-512}) .NET System.Security.Cryptography.SHA256Managed System.Security.Cryptography.SHA384Managed System.Security.Cryptography.SHA512Managed System.Security.Cryptography.RIPEMD160Managed 3.4.4 CryptoAPI / CAPICOM CryptCreateHash() CryptHashData() CryptHashMessage() CryptHashPublicKeyInfo() CryptHashSessionKey() CryptVerifyDetachedMessageHash() CryptVerifyMessageHash() ALG_ID ∈ {CALG_SHA_256, CALG_SHA_384, CALG_SHA-512} 3.5 Best Practices 3.5.1 SHA-256 SHA-256 ist kryptographisch sicher, einfach zu handhaben und wird von allen gängigen Frameworks unterstützt. 3.5.2 Hashwerte der Länge 256 bit und größer Die kryptographische Stärke eines Hashwertes ist vergleichbar mit der halben Schlüsselstärke symmetrischer Algorithmen. Bspw. ist SHA-256 vergleichsweise resistent gegen Brute-Force-Angriffe wie AES-128. Da man von symmetrischen Algorithmen weiß, dass Schlüssellängen unter 100 bit schwach sind, müssen Hashwerte von mind. 256 bit Länge (32 Bytes) eingesetzt werden. 3.5.3 Hashing anstatt Verschlüsselung Hash-Algorithmen sind Einwegfunktionen, d.h. es ist nicht möglich, aus einem Hashwert die zugrunde liegende Eingabe zu rekonstruieren. Daher sollte, wann immer möglich, auf eine Verschlüsselung verzichtet und stattdessen der Hashwert einer vertraulichen Information berechnet werden. Beispiel Passwörter sind ausschließliches Eigentum ihres jeweiligen Besitzers und dürfen nicht maschinell rekonstruierbar sein. 3.5.4 Salted Hashing anstatt Hashing Kurze Eingaben wie bspw. Passwörter sollten über einen zusätzlichen Salt abgesichert werden (siehe Abschnitt "Salted Hashing"). 3.5.5 Vergleich langer Eingaben Müssen lange Eingaben miteinander verglichen werden, so ist es praktikabler, deren Hashwerte zu berechnen und diese miteinander zu vergleichen. Beispiel Duplikatsprüfung bei eingehenden Aufträgen, die in Form von XML-Dokumenten in eine Queue eingestellt werden. 3.5.6 Integritätsprüfung Die Dateien, aus denen sich eine Applikation zusammensetzt, sollten vor ihrer Verwendung einer Integritätsprüfung unterzogen werden. Dies betrifft Executables, Libraries und Konfigurationsdateien. Auf diese Weise können schadhafte Manipulationen nach dem Buildprozess entdeckt werden. Die Integritätsprüfung erfolgt, indem die Anwendung vor der Verwendung einer Datei deren Hashwert berechnet und mit demjenigen Hashwert vergleicht, der innerhalb des Build-Prozesses im Vorfeld von dem Build-Master für diese Datei berechnet wurde. 3.5.7 Hashwerte verschlüsselt übertragen Hashwerte, die zur Integritätsprüfung einer Datei oder eines Downloads dienen, müssen verschlüsselt übertragen werden. Ein Angreifer könnte ansonsten die übertragenen Daten abhören, modifizieren, hashen und erneut absenden. 3.5.8 Digitale Signatur statt Hashing Statt Prüfsummen sollten digitale Signaturen für die Verifikation von Code und Downloads verwendet werden. Private Schlüssel müssen nicht übertragen werden und sind insgesamt besser gegen Angriffe abgesichert. Zudem wird Code Signing durch X.509v3-Zertifikate unterstützt. 3.6 Worst Practices 3.6.1 MD5 MD5 wurde im Dezember 2008 kryptographisch gebrochen: MD5 weist eine Kollisionsschwäche auf, die es ermöglicht, eine Eingabe derart zu manipulieren, dass sie den gleichen MD5-Hashwert aufweist wie eine andere Eingabe! Obwohl dieser Algorithmus in der Praxis weit verbreitet1 ist, darf er fortan nicht mehr verwendet werden. 3.6.2 SHA-1 Obwohl SHA-1 in der Praxis weit verbreitet ist und von allen gängigen Frameworks unterstützt wird, sollte SHA-1 aufgrund bekannter Kollisionsangriffe und aufgrund der zu kurzen Hashwertlänge (128 bit) nicht eingesetzt werden. Falls kein besseres Hashverfahren zur Verfügung steht, gilt die salvatorische Klausel (siehe Abschnitt am Ende des Dokuments). 1 in PGP und zur Berechnung von Dateiprüfsummen zwecks Integritätsprüfung 3.7 Rules of Thumb 3.7.1 Kollisionsfreiheit Hashwerte der Länge 256 bit können bis zu 2 in etwa einem Wertebereich von 10 Für gewöhnlich treten unter 10 76 76 256 verschiedene Dokumente darstellen. Dies entspricht unterschiedlichen Hashwerten. Dokumenten keine Duplikate auf. Solange der ausgewählte Hashalgorithmus (praktisch) kollisionsfrei ist, können Hashwerte in der Praxis kryptographisch sicher für die Integritätsprüfung von Nachrichten und Dateien eingesetzt werden. 4 Salted Hashing Hashverfahren verhindern, dass die eingegebenen Daten nachträglich rekonstruiert werden können. Für die bei einem Anmeldeverfahren eingesetzten Passwörter ist dies eine unabdingbare Eigenschaft. Allerdings ist es mit hohem Rechenaufwand und hoher Parallelität möglich, die Hashwerte aller (!) möglichen Eingaben zu berechnen (Brute-Force-Angriff). Das Ergebnis einer solch komplexen Berechnung sind sog. Rainbow Tables: ein Nachschlagewerk, das bei Eingabe eines Hashwertes die zugehörigen Originaldaten preisgibt. Rainbow Tables werden verteilt in Botnetzen berechnet und frei für Abfragen im Internet feilgeboten. Da gleiche Passwörter auch gleiche Hashwerte implizieren, müssen die Hashwerte für Passwörter besonders gegen diese Art von Angriff abgesichert werden. Zu diesem Zweck wird in den berechneten Hashwert „etwas Salz eingestreut“ (salted hashing). Hierdurch steigt der Aufwand für eine Brute-Force-Berechnung unverhältnismäßig hoch an. Abbildung: Salted Hashing Beim Salted Hashing wird ein Passwort als Bytefolge dargestellt. Nachdem der Hashwert für diese Bytefolge berechnet wurde, wird eine weitere Bytefolge fester Länge erzeugt und mit zufälligen Werten gefüllt (sog. Salt). Dieser Salt fließt in eine weitere Hashberechnung über den bereits berechneten Hashwert ein. Das Ergebnis wird als Salted Hash bezeichnet. Beide Bytefolgen, der Salted Hash und der Salt selbst, werden dann als konkatenierte Bytefolge gespeichert. Der Salt wird für jedes Passwort individuell erzeugt. Auf diese Weise ergeben unterschiedliche Passwörter unterschiedliche Hashwerte. Ein Brute-Force-Angriff kann nun nicht mehr auf den HashAlgorithmus als Ganzes angesetzt werden, sondern muss unter Berücksichtigung der individuellen Salts für jeden einzelnen Salted Hash eigene Rainbow Tables erzeugen. Empfehlungen: Salts sollten mind. vier Bytes lang sein, besser acht Bytes lang. Um einen höheren Sicherheitsgrad zu erreichen, sollten Salts getrennt von den Hashwerten gespeichert werden. 5 Message Authentication Codes Um Nachrichten vor unbemerkter Manipulation zu schützen, kann anstelle digitaler Signaturen ein alternativer Ansatz gewählt werden: sog. Message Authentication Codes. Dabei handelt es sich um einen Authentifizierungscode, der vom Absender einer Nachricht berechnet und verschlüsselt wird. Stimmt der entschlüsselte Authentifizierungscode des Absenders mit dem vom Empfänger berechneten Authentifizierungscode überein, so wurde die Nachricht auf dem Weg vom Absender zum Empfänger (vermutlich) nicht modifiziert. Der Authentifizierungscode selbst wird bei der Übertragung an den Empfänger durch eine symmetrische Verschlüsselung abgesichert. Absender und Empfänger teilen somit ein Geheimnis, den symmetrischen Schlüssel. Aus diesem Grund dient der Authentifizierungscode bei diesem Verfahren gleichzeitig zur Authentisierung der beiden Kommunikationspartner. Ein Message Authentication Code (MAC) signiert in diesem Sinne eine Nachricht und gewährleistet damit die Integrität und Authentizität einer Nachricht. Die Nachricht selbst wird allerdings nicht verschlüsselt. Technisch gesehen ist ein MAC der symmetrisch verschlüsselte Hashwert einer Nachricht. Da der symmetrische Schlüssel direkt in das Hashverfahren einschließt, ergeben unterschiedliche Schlüssel unter Verwendung desselben Hashverfahrens auch unterschiedliche MACs. 5.1 Sichere MAC-Verfahren Hash-based Message Authentication Code (HMAC) kombiniert eine sichere symmetrische Verschlüsselung mit einem sicheren Hashverfahren (z.B. HMAC-SHA-256). HMAC wird u.a. in den Transportprotokollen TLS und IPsec eingesetzt. Im Gegensatz zu hash-basierten MACs basiert ein Cipher-based Message Authentication Code (CMAC) auf einem symmetrischen Blockzifferverfahren (z.B. AES-CMAC). Dabei werden die gleichen Sicherheitsziele wie bei HMAC erreicht. Üblicherweise werden CMACs genau dort eingesetzt, wo symmetrische Verschlüsselungsverfahren effizienter verfügbar sind als Hashverfahren (z.B. Crypto Accelerator). MAC-3DES-CBC setzt für die symmetrische Verschlüsselung das TripleDES-Verfahren mit Cipher Block Chaining ein. Beide Verfahren werden auch als Keyed Hash Algorithm bezeichnet, da der Hashberechnung ein (symmetrischer) Schlüssel zugrunde liegt. 5.2 Unterstützung in Libraries und Frameworks 5.2.1 OpenSSL openssl dgst -alg –hmac 5.2.2 (alg ∈ {sha256, sha384, sha512, ripemd160}) Java Cryptography Architecture javax.crypto.KeyGenerator (algorithm ∈ {HmacSHA256, HmacSHA384, HmacSHA512}) javax.crypto.Mac (algorithm ∈ {HmacSHA256, HmacSHA384, HmacSHA512}) 5.2.3 .NET System.Security.Cryptography.KeyedHashAlgorithm.HMACSHA256 System.Security.Cryptography.KeyedHashAlgorithm.HMACSHA384 System.Security.Cryptography.KeyedHashAlgorithm.HMACSHA512 System.Security.Cryptography.KeyedHashAlgorithm.HMACRIPEMD160 System.Security.Cryptography.KeyedHashAlgorithm.MACTripleDES 5.2.4 CryptoAPI / CAPICOM CryptCreateHash() CryptHashData() CryptHashMessage() CryptHashPublicKeyInfo() CryptHashSessionKey() CryptVerifyDetachedMessageHash() CryptVerifyMessageHash() ALG_ID ∈ {CALG_HMAC, CALG_MAC} 5.3 Best Practices 5.3.1 HMACSHA256 und AES-CMAC-256 HMACSHA256 ist kryptographisch sicher, einfach zu handhaben und wird von allen gängigen Frameworks unterstützt. Einige Hardware Security Modules (HSM) unterstützen den ebenfalls als sicher eingestuften Algorithmus AES-CMAC-256. 5.3.2 Verwendung langer Schlüssel Als Schlüssel sollten lange Folgen kryptographisch sicherer Zufallszahlen verwendet werden (z.B. 24 Bytes). Wird ein Passwort als Vorlage für den Schlüssel eingesetzt, so muss zunächst eine PasswortSicherheitspolitik befolgt werden, die starke Passwörter vorschreibt. Starke Passwörter sind mind. 12 Zeichen lang, bestehen aus Groß- und Kleinbuchstaben, Ziffern und Sonderzeichen, sind nicht erratbar und in keinem Wörterbuch aufgeführt. Zudem ist der Algorithmus PBKDF2 für die Ableitung eines Schlüssels von dem vorgegebenen Passwort einzusetzen (siehe Abschnitt Symmetrische Verschlüsselung, Best Practices). Eigene Kodierungen sind nicht erlaubt. 5.3.3 Digitale Signaturen Szenarien, die eine hohe Sicherheit erfordern, sollten nicht über ein MAC-Verfahren, sondern über digitale Signaturen abgesichert werden. Digitale Signaturen setzen kein gemeinsames Geheimnis zwischen Absender und Empfänger einer Nachricht voraus, sondern verwenden verteilte Schlüssel. 6 Symmetrische Verschlüsselung Bei einer symmetrischen Verschlüsselung verwenden Absender und Empfänger einer Nachricht denselben Schlüssel. Abbildung: Symmetrische Verschlüsselung Beispiel: Symmetrischer Schlüssel (AES 256 bit) 94 d3 37 45 25 62 37 32 fd 17 3c e2 c5 29 df d2 32 22 59 9b 76 38 77 b8 d2 47 5e 64 a3 18 19 46 Die Verschlüsselung großer Datenmengen erfolgt blockweise. Initial fließt ein Vektor mit zufällig generierten Daten in den Verschlüsselungsprozess ein (sog. Initialisierungsvektor). Die Inhalte dieses Vektors verändern sich während der blockweisen Verschlüsselung zusammen mit den im vorherigen Schritt erzeugten Geheimdaten. Auf diese Weise wird verhindert, dass gleiche Klartextblöcke auf identische Verschlüsselungsblöcke abgebildet werden, wodurch Rückschlüsse auf den verwendeten Schlüssel gezogen werden könnten. Beispiel: Initialisierungsvektor (128 bit) c2 f9 78 df ea 20 e8 04 5b d7 94 0c 99 49 41 fa 6.1 Schlüsselaustausch Der Nachteil einer symmetrischen Verschlüsselung ist der Umstand, dass sich die beiden Kommunikationspartner im Vorfeld auf einen gemeinsamen, geheimen Schlüssel verständigen müssen. Dieser Austausch muss auf einem sicheren Wege unter Ausschluss Dritter erfolgen. Der Initialisierungsvektor selbst muss nicht geheim bleiben, da er aus zufälligen Zahlen generiert wird. Der eingesetzte Verschlüsselungsalgorithmus (engl. cipher) darf ebenfalls öffentlich bekannt sein. Geheim bleiben muss lediglich der verwendete Schlüssel. 6.2 Sichere symmetrische Algorithmen Algorithmus Schlüssellänge Blocklänge 128 bit 128 bit 192 bit 192 bit 256 bit 256 bit Triple DES 168 bit 64 bit Blowfish Blowfish 128..448 bit 64 bit Twofish Twofish 128 bit AES-128 AES-192 Advanced Encryption Standard AES-256 3DES 192 bit 128 bit 256 bit Stand: 12/2012 6.3 Unterstützung in Libraries und Frameworks 6.3.1 OpenSSL openssl enc -cipher cipher ∈ {aes128, aes192, aes256, aes-128-cbc, aes-192-cbc, aes-256-cbc, bf, bf-cbc, blowfish, des3} 6.3.2 Java Cryptography Architecture javax.crypto.Cipher algorithm ∈ {AES, AESWrap, Blowfish, DESede, DESedeWrap} javax.crypto.KeyGenerator algorithm ∈ {AES, Blowfish, DESede} java.security.AlgorithmParameters algorithm ∈ {AES, Blowfish, DESede} javax.crypto.SecretKeyFactory 6.3.3 algorithm ∈ {AES, DESede} .NET ab Version 3.0: System.Security.Cryptography.AesManaged System.Security.Cryptography.AesCryptoServiceProvider seit Version 2.0: System.Security.Cryptography.RijndaelManaged System.Security.Cryptography.TripleDESCryptoServiceProvider 6.3.4 CryptoAPI / CAPICOM CryptEncrypt() CryptDecrypt() CryptEncryptMessage() CryptDecryptMessage() ALG_ID ∈ {CALG_3DES, CALG_3DES_112, CALG_AES, CALG_AES_128, CALG_AES_192, CALG_AES_256} 6.4 Best Practices 6.4.1 AES-256 AES-256 wird als weit verbreiteter Standard von allen gängigen Frameworks unterstützt, ist performant und kryptographisch sicher. 6.4.2 Schlüssel der Länge 128 bit und größer Verschlüsselungen mit einer Stärke unter 128 bit sind schwach und anfällig für Brute-Force-Angriffe. Daher müssen symmetrische Schlüssel von mind. 128 bit Länge eingesetzt werden. 6.4.3 Schlüssel der Länge 256 bit Mit Schlüsseln der Stärke 256 bit können Brute-Force-Angriffe praktisch ausgeschlossen werden (2 256 6.4.4 entspricht ungefähr 10 76 möglichen Schlüsselwerten). SSL anstatt symmetrischer Verschlüsselung Eine gesicherte Kommunikationsleitung auf Basis von SSL 3.0 / TLS 1.0 ist jeder eigenhändigen Verschlüsselung vorzuziehen, sowohl aus Aufwands- wie aus Performancegründen. 6.4.5 Hybride Verschlüsselung statt symmetrischer Verschlüsselung Hybride Verschlüsselungsverfahren zeichnen sich durch eine besonders starke Absicherung der eingesetzten Schlüssel aus und sollten daher einer einfachen symmetrischen Verschlüsselung stets vorgezogen werden (siehe Abschnitt "Hybride Verschlüsselung"). 6.4.6 Schlüsselgenerierung Ein symmetrischer Schlüssel sollte aus kryptographisch sicheren Zufallszahlen zusammengesetzt werden (siehe Abschnitt "Zufallszahlen"). 6.4.7 Initialisierungsvektor Um den eingesetzten Schlüssel vor Brute-Force-Angriffen zu schützen, muss jeder symmetrischen Verschlüsselung ein Initialisierungsvektor (IV) mit zufällig erzeugtem Inhalt zugrunde gelegt werden. Der IV fließt in die Verschlüsselung des ersten Datenblocks ein und verändert seinen Inhalt mit jeder weiteren Blockverschlüsselung. Initialisierungsvektoren sollten nicht wiederverwendet werden. Vielmehr sollte für jede Applikationsinstanz bzw. Session ein neuer Intialisierungsvektor generiert werden. Bei besonders sensiblen Daten sollte vor jeder Verschlüsselung ein neuer Initialisierungsvektor erzeugt werden. Initialisierungsvektoren müssen nicht geheim gehalten werden2. Allerdings sollten sie ausschließlich der verschlüsselnden sowie der entschlüsselnden Instanz bekannt sein. 6.4.8 Cipher Block Chaining (CBC) Der Initialisierungsvektor allein schützt den eingesetzten Schlüssel nicht vor wiederholt auftretenden Geheimtextblöcken. Eine weitere wichtige Schlüsselsicherheit wird durch die Anwendung des sog. Cipher Block Chaining (CBC) erreicht. Bei diesem Blockmodus wird jeder Klartextblock vor seiner Verschlüsselung durch eine bitweise XOR-Operation mit dem vorhergehenden Geheimtextblock verknüpft. Hierdurch ergeben sich stets unterschiedliche Geheimtextblöcke, selbst wenn der Klartext gleiche Datenblöcke enthält. Als Blockmodus sollte CBC eingesetzt werden. Die Blockmodi Cipher Feedback (CFB), Cipher Text Stealing (CTS) und Output Feedback (OFB) gelten ebenfalls als sicher, sollten aber nur in begründeten Ausnahmen eingesetzt werden (bspw. wenn CBC nicht verfügbar sein sollte). 6.4.9 PKCS #7 Padding I.d.R. muss der letzte zu verschlüsselnde Klartextblock auf die dem Algorithmus zugrunde liegende Blockgröße aufgefüllt werden. Dieses als „Padding“ bezeichnete Anfügen von Zeichen sollte über den Standard „Public Key Cryptography Standards #7“ erfolgen. PKCS #7 ist weit verbreitet und wird von allen gängigen Frameworks unterstützt. 2 Einem Kryptoanalysten, der n Geheimtextblöcke analysiert, sind bei Einsatz des Blockmodus Cipher Block Chaining bereits n-1 Initialisierungsvektoren bekannt, denn: Der Geheimtext des Blocks B(n-1) geht als Initialisierungsvektor in die Verschlüsselung des Blocks B(n) ein. 6.4.10 Schlüssel von einem Passwort ableiten Wird ein symmetrischer Schlüssel aus einem Passwort oder aus einer Passphrase abgeleitet, so muss hierfür ein kryptographisch sicherer Algorithmus verwendet werden. Als Standard eignet sich besonders Password-Based Key Derivation Function (PBKDF2, RFC 2898). PBKDF2 fügt dem Passwort einen Salt hinzu und wendet darauf eine Hashfunktion, eine symmetrische Verschlüsselung und/oder einen Message Authentication Code an. Dieser Prozess wird mehrfach wiederholt, um den auf diese Weise konstruierten Schlüssel gegen Password Cracking zu härten. Auf diese Weise können kryptographisch sichere Schlüssel von beliebiger Länge erzeugt werden (z.B. 256 Bytes). PBKDF2 ist eine weit verbreitete Schlüsselableitungsfunktion und wird in zahlreichen Frameworks und Standard-Implementationen eingesetzt, bspw. OpenSSL: openssl enc Java: javax.crypto.spec.PBEKeySpec .NET: System.Security.Cryptography.Rfc2898DeriveBytes CryptoAPI / CAPICOM: CryptDeriveKey(), CPDeriveKey() sowie in WPA2, WinZip, TrueCrypt, OpenDocument. 6.4.11 Starke Passwörter Werden Passwörter als Vorlage für symmetrische Schlüssel verwendet (siehe PBKDF2), so sollten diese Passwörter mind. 12 Zeichen lang sein. Ein Passwort von weniger als 12 Zeichen Länge kann innerhalb von wenigen Wochen über einen Brute-Force-Angriff gebrochen werden. 6.5 Worst Practices 6.5.1 DES Der weit verbreitete Algorithmus „Data Encryption Standard (DES)“ ist mit seiner Schlüssellänge von 56 bit besonders anfällig für Brute-Force-Angriffe. Gleiches gilt für RC5. 6.5.2 Electronic Code Book (ECB) Der Padding-Modus „Electronic Code Book (ECB)“ verschlüsselt jeden Klartextblock individuell und unabhängig von den vorherigen Blöcken. Identische Klartextblöcke werden somit auf identische Geheimtextblöcke abgebildet. Enthält der Klartext viele Wiederholungen, kann der eingesetzte Schlüssel gebrochen werden, in dem der Geheimtext an den sich wiederholenden Stellen blockweise entschlüsselt wird. 6.5.3 Daten auf einer durchgehend abgesicherten Leitung zweifach verschlüsseln Daten, die ausschließlich über eine gesicherte Leitung transportiert werden (z.B. SSL), sollten nicht ein weiteres Mal verschlüsselt werden. Eine zweifache Verschlüsselung bringt keine Verbesserung und bedeutet einen Performance-Verlust auf Seiten des Absenders und des Empfängers. Anders verhält es sich, wenn die Datenpakete das gesicherte Netz (zwischenzeitlich) verlassen. In diesem Fall sind die zu schützenden Daten im Sinne einer Point-to-Point-Verschlüsselung am Endpunkt des Senders zu verschlüsseln und am Endpunkt des Empfängers zu entschlüsseln. Dies gilt i.S. eines defensiven Ansatzes insbesondere dann, wenn der Entwickler keine Kenntnis über die Auslegung und Absicherung des Netzwerks besitzt. 6.5.4 Verschlüsselte Daten komprimieren Die Komprimierung von bereits verschlüsselten Daten erbringt keine nennenswerte Einsparung der Datenmenge: bewährte Verschlüsselungsalgorithmen erzeugen Ausgaben, die sich, statistisch gesehen, von einer Reihe von Zufallszahlen kaum unterscheiden lassen. Komprimierungsalgorithmen suchen jedoch nach Wiederholungsmustern, die in sorgfältig verschlüsselten Daten so gut wie niemals auftreten. Hingegen mag es sinnvoll sein, die ursprünglichen Daten vor ihrer Verschlüsselung zu komprimieren: Wird die Datenmenge hierbei signifikant verkleinert, können bei der anschließenden Verschlüsselung viele Blöcke respektive CPU-Zyklen eingespart werden. Zudem enthalten komprimierte Daten kaum Redundanzen, so dass Angriffe auf den Schlüssel noch schwieriger sind. 6.6 Rules of Thumb 6.6.1 Twofish statt Blowfish Obwohl bis dato kein effizienter Angriff gegen den Algorithmus „Blowfish“ bekannt ist, empfiehlt der Urheber Bruce Schneier die Verwendung seines Nachfolgers „Twofish“. 6.6.2 Schlüsselstärke von Triple DES Als Weiterentwicklung von DES verwendet Triple DES drei DES-Schlüssel der Länge 56 bit, d.h. einen Gesamtschlüssel der Länge 168 bit. Bedingt durch die Möglichkeit eines Man-in-the-MiddleAngriffs beträgt die effektive Schlüsselstärke jedoch nur 112 bit. TripleDES ist kryptographisch vergleichsweise so sicher wie ein 128bit Schlüssel. 6.6.3 Encoding synchronisieren Bei der symmetrischen Ver- und Entschlüsselung ist darauf zu achten, dass Absender und Empfänger dieselbe Zeichenkodierung verwenden (z.B. UTF-8). 6.6.4 Laufzeitvorteil von AES AES verschlüsselt schneller als TripleDES und bietet gleichzeitig eine höhere Sicherheit (da größere Schlüssel gewählt werden können). 7 Asymmetrische Verschlüsselung Bei einer asymmetrischen Verschlüsselung verwenden Absender und Empfänger einer Nachricht unterschiedliche Schlüssel. Ein vorheriger Schlüsselaustausch zwischen den beiden Kommunikationspartnern ist nicht erforderlich. Die für die Verschlüsselung und Entschlüsselung eingesetzten Schlüssel setzen sich aus zwei Bestandteilen zusammen: einem privaten Schlüssel (private key) und einem öffentlichen Schlüssel (public key). Beide Schlüsselteile sind mathematisch fest miteinander verbunden, nicht substituierbar und nicht ableitbar3. Ein derart zusammen gehöriges Schlüsselpaar bezeichnet man als Public/Private-Key. Der private Schlüssel ist geheim und darf nicht an Dritte weitergegeben werden. Der öffentliche Schlüssel ist allgemein zugänglich und kann an alle potentiellen Kommunikationspartner verteilt werden. Public/Private-Key-Schlüsselpaare werden auf der Basis sehr großer Primzahlen konstruiert und sind aufgrund ihrer mathematischen Komplexität praktisch nicht brechbar4. Beispiel: Public Key (RSA, 1024 bit) <RSAKeyValue> <Modulus> b9 57 b2 ca 89 71 0a d4 77 7c af db 61 c3 36 f2 27 bf 3a 4e 06 82 05 a6 a8 44 d0 ac 7b 46 c9 28 c9 7a 80 e1 a7 c3 09 ad cb b6 d8 b4 8b 1a 6b fe 56 e7 fc 40 bf 1f 02 47 6b 2c 09 bd 1a 82 3b 27 ae be f3 cb c0 f5 71 2f e4 d7 59 b5 a4 52 44 20 0a 51 e9 dc d9 24 04 60 8c e5 1e 9a 93 9f f1 20 c6 3a 0d 06 ea ca 43 6c 97 f8 fd f1 c2 8d bb 8d 6d 8f 95 30 b2 51 8a 66 4c d7 23 1b 85 32 b0 9c </Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> 3 Der öffentliche Schlüssel lässt sich von dem privaten Schlüssel ableiten, nicht aber in der umgekehrten Richtung. 4 Jeder noch so große Schlüssel kann mit dem entsprechenden Einsatz der Ressourcen Zeit, Leistung und Kosten gebrochen werden. Daher geht man davon aus, dass die Information, die durch einen gebrochenen Schlüssel aufgedeckt wurde, zum Zeitpunkt dieser nicht-authorisierten Einsichtnahme veraltet und wertlos geworden ist. Beispiel: zugehöriger Private Key (RSA, 1024 bit) <RSAKeyValue> <Modulus> b9 77 27 a6 c9 c3 d4 f2 05 46 a7 b4 36 82 7b e1 d8 e7 06 ac 80 b6 56 47 d0 7a cb fe 02 82 c9 ad 6b 1f 1a cb 09 1a bf bd f3 d7 8b 40 09 be e4 20 fc 2c ae 2f 44 24 6b 27 71 52 d9 9a 3b f5 a4 dc 1e 3a c0 b5 e9 e5 c6 6c 59 51 8c 20 43 8d 0a 60 f1 ca c2 30 04 9f ea f1 95 d7 93 06 fd 8f 4c 9c 0d f8 6d 66 b0 0a 97 8d 8a 32 71 c3 bb 51 85 89 61 b2 1b ca db 4e 23 b2 af 3a 44 57 7c bf a8 28 </Modulus> <Exponent>AQAB</Exponent> <P> e2 52 b1 be 4d 38 cb 0e c8 a6 b8 9e ba da 41 8c 77 0d ce 82 e2 34 3c e3 84 1c 7e 95 c3 f4 67 9f 71 93 19 b4 99 10 6f dd c2 0a 27 96 74 f7 f1 2c c8 d5 c4 d0 1c 7e aa c8 ae 33 37 57 a0 4a 89 77 </P> <Q> d2 32 31 d9 5c ed 09 74 88 0c be 09 0a ed 6a bf e7 1e cb 53 76 62 09 6e 68 5e 5a a3 79 94 58 2e 6f 97 03 0f e9 01 a8 b8 c7 bc 31 ea d3 65 df a8 9a 8a bd e3 b2 a7 59 ac c5 52 7a 8e 5e a8 5c 15 </Q> <DP> 7e c7 a4 19 de 58 3a 27 85 ef 1e ec 8b ef 47 58 d0 38 43 be bd c8 55 73 7d c6 18 82 fc ca 24 62 04 d5 4a 49 08 95 54 94 fc e5 83 57 9d 1e 67 53 97 0d 68 ba cb bb 89 1f f1 b5 6f 02 ff 1f c1 f1 </DP> <DQ> 7e c7 a4 19 de 58 3a 27 85 ef 1e ec 8b ef 47 58 d0 38 43 be bd c8 55 73 7d c6 18 82 fc ca 24 62 04 d5 4a 49 08 95 54 94 fc e5 83 57 9d 1e 67 53 97 0d 68 ba cb bb 89 1f f1 b5 6f 02 ff 1f c1 f1 </DQ> <InverseQ> c2 94 bf 57 4a 79 d6 c0 7e 23 4a d4 7f ed 57 f6 19 23 f2 8f 8f eb c7 96 8c 17 6e 46 7c 31 35 51 f4 62 d4 77 fc 73 52 b3 67 bf 98 c4 04 c8 99 cb 87 48 36 f4 88 55 e5 cc de 7f f7 77 46 b8 62 d4 </InverseQ> <D> b2 e4 1e 20 48 14 a9 16 ae f9 d6 64 e7 13 54 19 54 f6 6f b1 b9 b1 49 0a </D> </RSAKeyValue> d2 05 d5 c5 32 88 19 19 da 92 6d ba 17 9d b8 11 67 92 c6 1d 07 fc 0b 20 b1 89 f4 b6 07 d7 5f d6 e2 e4 b8 fa e0 b9 6a 38 61 c4 48 94 ad 0b 73 09 e4 24 e9 27 92 7d d2 b3 c7 cf e7 59 8e 82 46 f2 be 8e e7 f2 29 a0 5f c9 5b 4e 76 90 da c1 b0 d2 c2 df f9 71 40 7f 32 2a a1 d3 e2 32 b7 3c da e3 b3 a3 61 ca 4e e9 3c f2 Öffentliche Schlüssel werden als Bestandteil eines digitalen Zertifikats verteilt: Abbildung: Zertifikat Jeder Kommunikationspartner besitzt ein weltweit eindeutiges Schlüsselpaar. Um eine Nachricht sicher an den vorgesehenen Empfänger zu übertragen, verschlüsselt der Absender die Nachricht mit dem öffentlichen Schlüssel des Empfängers. Nur dieser ist mit Hilfe seines privaten Schlüssels in der Lage, die Nachricht zu entschlüsseln. Abbildung: Asymmetrische Verschlüsselung 7.1 Geheimhaltung Eine kryptographisch sichere Kommunikation auf Basis einer asymmetrischen Verschlüsselung beruht auf der Annahme, dass private Schlüssel geheim bleiben. Die Ablage muss in einem besonders geschützten Bereich des Betriebssystems (z.B. KeyStore oder CertificateStore) erfolgen, auf den ausschließlich der Besitzer des privaten Schlüssels Zugriff hat. Bestenfalls ist der private Schlüssel auf einer Hardware gespeichert und kann nur durch die explizite Freigabe durch ihren Besitzer eingesetzt werden (z.B. SmartCard/PIN, oder für Hochsicherheitsanforderungen: Hardware Security Module in Verbindung mit einer SmartCard). 7.2 Sichere asymmetrische Verschlüsselungsalgorithmen Algorithmus RSA Rivest, Shamir, Adleman Schlüssellänge 2048..16.384 bit in 8 bit-Schritten Stand: 12/2012 7.3 Unterstützung in Libraries und Frameworks 7.3.1 OpenSSL openssl rsautl 7.3.2 Java Cryptography Architecture java.security.KeyPairGenerator (algorithm ∈ {RSA}) java.security.KeyFactory (algorithm ∈ {RSA}) javax.crypto.Cipher (algorithm ∈ {RSA}) 7.3.3 .NET System.Security.Cryptography.RSACryptoServiceProvider 7.3.4 CryptoAPI / CAPICOM CryptEncrypt() CryptDecrypt() CryptEncryptMessage() CryptDecryptMessage() ALG_ID ∈ { CALG_RSA_SIGN } 7.4 Best Practices 7.4.1 RSA-2048 RSA-2048 wird als weit verbreiteter Standard von allen gängigen Frameworks unterstützt und ist kryptographisch sicher. Für die Übertragung vertraulicher Information über einen unsicheren Kommunikationskanal sollte RSA-2048 für die Dauer einer Session eingesetzt werden. Da ein Angreifer für das Brechen eines Schlüssels Rechenleistung und Zeit benötigt, wird im Hinblick auf die langfristige Aufbewahrung von asymmetrisch verschlüsselter Information RSA mit einer Schlüssellänge größer als 2048 eingesetzt werden (z.B. RSA-4096 oder RSA-8192). 7.4.2 Hybride Verschlüsselung Aufgrund der komplexen mathematischen Berechnungen, die eine asymmetrische Verschlüsselung erfordert, sollten Nutzdaten grundsätzlich symmetrisch verschlüsselt werden. Der dabei eingesetzte symmetrische Schlüssel (sog. Session Key) wird hingegen asymmetrisch verschlüsselt (siehe Abschnitt "Hybride Verschlüsselung"). 7.4.3 Versand an mehrere Empfänger Nur der Besitzer des zugehörigen privaten Schlüssels ist in der Lage, eine mit seinem öffentlichen Schlüssel verschlüsselte Nachricht zu entschlüsseln. Soll eine Nachricht an mehrere Empfänger verschickt werden, so muss diese Nachricht für jeden Empfänger einzeln verschlüsselt werden (und zwar jeweils mit dem öffentlichen Schlüssels des jeweiligen Empfängers). Aus Performancegründen verschlüsselt man die Nachricht in der Praxis nur ein einziges Mal symmetrisch. Lediglich der dabei eingesetzte symmetrische Schlüssel wird mehrfach mit den öffentlichen Schlüsseln Verschlüsselung"). der einzelnen Empfänger verschlüsselt (siehe Abschnitt "Hybride 7.5 Worst Practices 7.5.1 RSA-1024 RSA-1024 wird aufgrund der vergleichsweise geringen Schlüssellänge und drohender Angriffsszenarien in der Praxis vom BSI nicht mehr empfohlen. Stattdessen sollten RSA-Schlüssel der Länge 2048 und größer eingesetzt werden. 7.5.2 Inhalte asymmetrisch verschlüsseln Eine asymmetrische Verschlüsselung ist mind. 1.000 Mal langsamer als eine symmetrische Verschlüsselung. Zudem können nur sehr kleine Datenblöcke asymmetrisch verschlüsselt werden. Aus diesen Gründen sollten Daten stets symmetrisch verschlüsselt werden. Der dabei eingesetzte symmetrische Schlüssel ist vergleichsweise sehr klein und kann ohne nennenswerte PerformanceEinbußen asymmetrisch verschlüsselt werden. 8 Eine Hybride Verschlüsselung hybride Verschlüsselung kombiniert asymmetrische und symmetrische Verschlüsselungsverfahren. Dabei werden die Daten selbst symmetrisch verschlüsselt. Nur der dabei eingesetzte symmetrische Schlüssel unterliegt einer asymmetrischen Verschlüsselung. Hybride Verschlüsselungen sind in der Praxis weit verbreitet und finden vor allem beim Aufbau einer SSL/TLS-Verbindung ihre Anwendung. Die folgende Abbildung verdeutlicht den Ablauf einer hybriden Verschlüsselung: Abbildung: Hybride Verschlüsselung Erläuterung: Hybride Verschlüsselung in einem gegenseitigen Authentisierungsverfahren Wenn sich ein Client mit einem Server verbinden möchte (Schritt 1), generiert der Server einen zufällig bestimmten, kryptographisch sicheren Sitzungsschlüssel (sog. Session-Key). Dieser SessionKey dient später der symmetrischen Verschlüsselung aller zwischen Client und Server ausgetauschten Nachrichten. Damit der Client verifizieren kann, dass der Session-Key von dem Server (und niemandem sonst) erzeugt wurde, signiert der Server den Session-Key. Zwecks sicherer Übertragung an den Client verschlüsselt der Server den Session-Key mit dem öffentlichen Schlüssel des Clients. Die Signatur sowie den verschlüsselten Session-Key sendet der Server zurück an den Client (Schritt 2). Der Client verifiziert die Server-Signatur (durch Anwendung des öffentlichen Server-Schlüssels). Bei gültiger Signatur hat sich der Server dem Client gegenüber authentisiert (Server-Authentisierung). Der Client entschlüsselt den Session-Key mit seinem privaten Schlüssel. Diesen Session-Key verwendet der Client fortan für die symmetrische Verschlüsselung und Entschlüsselung der mit dem Server ausgetauschten Nachrichten. Als nächstes muss sich der Client gegenüber dem Server authentisieren. Zu diesem Zweck signiert der Client den entschlüsselten Session-Key und schickt die Signatur gemeinsam mit dem SessionKey zurück an den Server (Schritt 3), letzteren (im Sinne einer sicheren Übertragung) natürlich verschlüsselt mit dem öffentlichen Server-Schlüssel. Der Server verifiziert die Signatur des Clients (durch Anwendung des öffentlichen Client-Schlüssels). Bei gültiger Signatur hat sich auch der Client gegenüber dem Server authentisiert (ClientAuthentisierung). Der Server entschlüsselt den Session-Key nun mit seinem privaten Schlüssel und vergleicht diesen Session-Key mit dem anfangs von ihm selbst generierten Session-Key. Sind beide Schlüssel identisch, so besteht nun eine sichere Kommunikationsverbindung zwischen Client und Server. Jede Nachricht, die fortan zwischen Client und Server ausgetauscht wird, wird von dem jeweiligen Absender mit dem gemeinsamen Session-Key verschlüsselt und von dem jeweiligen Empfänger wieder entschlüsselt (Schritte 4, 5, ...). Bei einem späteren Abbau der Verbindung löschen beide Parteien unwiderruflich den bislang für diese Session verwendeten Session-Key (Schritt n). Eine neue Verbindung zwischen den beiden Parteien erfordert die Erzeugung eines neuen Session-Keys. Der Session-Key ist somit nur für die Dauer einer Sitzung gültig. 8.1 Erreichen der kryptographischen Ziele Unter der Annahme, dass alle Kommunikationspartner ihren privaten Schlüssel geheim halten, erreicht eine auf diese Weise abgesicherte Kommunikation (z.B. AES-256 und RSA-2048) alle vier kryptographischen Ziele: Vertraulichkeit Jegliche Kommunikation erfolgt verschlüsselt. Integrität Nachrichten können auf ihrem Weg vom Absender zum Empfänger nicht verändert werden. Eine manipulierte Nachricht würde bei dem Versuch der Entschlüsselung auf einen (mathematischen) Fehler laufen. Dies gilt für Nutzdaten ebenso wie für den Austausch des Sitzungsschlüssels. Authentizität Client und Server authentisieren sich durch gegenseitige Signatur des vereinbarten Sitzungsschlüssels. Nichtabstreitbarkeit Die mathematische Natur asymmetrischer Schlüssel stellt sicher, dass niemand anderes als der Besitzer des für die Signatur eingesetzten privaten Schlüssels eine Nachricht unter seiner eigenen Identität signieren kann. 8.2 Unterstützung in Libraries und Frameworks 8.2.1 OpenSSL openssl smime –cipher (cipher ∈ {aes128, aes192, aes256, des3}) 8.3 Best Practices 8.3.1 Schnell und sicher Hybride Verschlüsselungsverfahren profitieren von der vergleichsweise hohen Geschwindigkeit einer symmetrischen Verschlüsselung sowie von der hohen Sicherheit einer asymmetrischen Verschlüsselung. Gleichzeitig unterliegt eine Verschlüsselungsverfahren: hybride Erstens Verschlüsselung wird nur eine nicht sehr den kleine Nachteilen Datenmenge der einzelnen asymmetrisch verschlüsselt (der eingesetzte symmetrische Schlüssel), und zweitens ist im Vorfeld kein Schlüsselaustausch zwischen den Kommunikationspartnern erforderlich. 9 Digitale Signatur Bei der asymmetrischen Verschlüsselung wendet der Absender den öffentlichen Schlüssel des Empfängers auf die Nachricht an. Aufgrund der mathematischen Natur der asymmetrischen Schlüssel kann ausschließlich der Besitzer des zugehörigen privaten Schlüssels, also der vorgesehene Empfänger, diese Nachricht entschlüsseln. Wendet der Absender hingegen seinen privaten Schlüssel auf die Nachricht an, ergibt sich ein zweites Anwendungsgebiet für Public/Private-Key-Schlüsselpaare: Da nur der Absender einen Zugriff auf seinen privaten Schlüssel hat, weiß der Empfänger, dass die Nachricht ausschließlich von eben diesem Absender stammen kann. Der Absender hat sich auf diese Weise gegenüber dem Empfänger authentisiert. Diesen Vorgang bezeichnet man als digitale Signatur. Der Empfänger kann die Signatur des Absenders verifizieren, in dem er den öffentlichen Schlüssel des Absenders auf die übermittelte Signatur anwendet. Ist die Entschlüsselung erfolgreich, so ist auch die Signatur gültig. Abbildung: Digitale Signatur In der Praxis wird der private Schlüssel nicht auf die gesamte Nachricht angewendet. Stattdessen wird ein Hashwert über den gesamten Nachrichteninhalt berechnet. Die Signatur besteht dann aus der Verschlüsselung des (kleinen) Hashwertes mit dem privaten Schlüssel des Absenders. Entsprechend verifiziert der Empfänger die Signatur der Nachricht, indem er den öffentlichen Schlüssel des Absenders auf den verschlüsselten Hashwert anwendet. Um zusätzlich die Unverfälschtheit der Nachricht sicherzustellen, berechnet der Empfänger den Hashwert der Nachricht erneut und vergleicht diesen mit dem entschlüsselten, vom Absender stammenden Hashwert (Integritätsprüfung). 9.1 Sichere Signaturalgorithmen Algorithmus Schlüssellänge RSA Rivest, Shamir, Adleman 2048..16.384 bit in 8 bit-Schritten DSA Digital Signature Algorithm 1024 bit ECDSA Elliptic Curve Digital Signature Algorithm 256 bit 384 bit 512 bit Stand: 12/2012 9.2 Unterstützung in Libraries und Frameworks 9.2.1 OpenSSL openssl dsaparam openssl gendsa -cipher openssl genrsa -cipher openssl dsa openssl rsa openssl dgst -alg cipher ∈ {aes128, aes192, aes256, des3} alg ∈ {dss1} alg ∈ {sha256, sha384, sha512, ripemd160} für RSA 9.2.2 für DSA Java Cryptography Architecture java.security.KeyPairGenerator algorithm ∈ {RSA, DSA} java.security.KeyFactory algorithm ∈ {RSA, DSA} java.security.AlgorithmParameterGenerator algorithm ∈ {DSA} java.security.AlgorithmParameters algorithm ∈ {DSA} java.security.Signature algorithm ∈ {SHA256withRSA, SHA384withRSA, SHA512withRSA, ECDSA, SHA256withECDSA, SHA384withECDSA, SHA512withECDSA} javax.crypto.Cipher 9.2.3 .NET ab Version 3.0: System.Security.Cryptography.ECDsaCng seit Version 2.0: System.Security.Cryptography.RSACryptoServiceProvider System.Security.Cryptography.DSACryptoServiceProvider algorithm ∈ {RSA} 9.2.4 CryptoAPI / CAPICOM CryptSignAndEncryptMessage() CryptDecryptAndVerifyMessageSignature() CryptSignHash() CryptSignMessage() CryptSignMessageWithKey() CryptVerifyDetachedMessageSignature() CryptVerifyMessageSignature() CryptVerifyMessageSignatureWithKey() CryptVerifySignature() ALG_ID ∈ { CALG_DSS_SIGN, CALG_ECDSA, CALG_RSA_SIGN } 9.3 Best Practices 9.3.1 DSA statt RSA DSA setzt eine Zufallszahl ein, so dass die Signaturen gleicher Daten mit dem gleichen Schlüssel unterschiedlich sind. Allerdings ist DSA um den Faktor 10-40 prozessor-intensiver. 9.3.2 Signaturverfahren mit Hashwerten der Länge 160 bit und größer Die Signatur einer Nachricht wird repräsentiert durch einen Hashwert dieser Nachricht, welcher mit dem privaten Schlüssel des Signierenden verschlüsselt wird. Signaturverfahren mit Hashwerten bis zu 128 bit Länge sind heute mit massiv parallelen Verfahren angreifbar. Aus diesem Grund sollte das Signaturverfahren mit einem Hashalgorithmus kombiniert werden, der Hashwerte mit mind. 160 bit Länge (20 Bytes) erzeugt (SHA-256, SHA-384, SHA-512). 9.3.3 Protokoll über alle signierten Dokumente führen Eine digitale Signatur ist rechtlich bindend: sie erzwingt die Nicht-Abstreibarkeit von Transaktionen in einer digitalen Welt. Für eventuelle Rechtsstreitigkeiten sollte ein Protokoll über alle jemals signierten Dokumente geführt werden: Wer hat wann welches Dokument signiert und an wen übermittelt? Dieses Protokoll sollte nicht-löschbar sein (Write-Once-Datenträger). 10 Schlüsselaustauschverfahren Bei der symmetrischen Verschlüsselung müssen beide Kommunikationspartner im Vorfeld einen gemeinsamen symmetrischen Schlüssel festlegen (Key Agreement). Im Idealfall wurde dieser Schlüssel bereits vor der Kommunikation über einen separaten Übertragungsweg ausgetauscht (z.B. persönlich). Kann der symmetrische Schlüssel erst zum Zeitpunkt des Verbindungsaufbaus festgelegt werden, so besteht das Problem, wie dieser Schlüssel auf der bislang unsicheren Leitung sicher zwischen den beiden Kommunikationspartnern ausgetauscht werden kann. Eine kryptographisch sichere Lösung bietet das Verfahren nach Diffie-Hellman. Dieses Schlüsselvereinbarungsverfahren setzt einige Parameter voraus, die im Vorfeld erzeugt und zwischen den beiden Kommunikationspartnern öffentlich ausgetauscht werden müssen: eine sehr große, zufällig bestimmte Primzahl p sowie ein Generatorwert g (typischerweise 2 oder 5). Beispiel: Diffie-Hellman-Parameter (1024 bit) prime: 00:95:3b:01:77:0f:b6:8a:ae:33:9f:ec:86:0b:99: 93:23:bf:d4:26:95:f0:26:f7:8f:b2:68:29:6d:36: 07:2c:27:dd:a7:60:11:71:2c:2d:d8:67:63:07:3a: 50:5f:bb:a6:0a:a2:fb:89:6b:c2:1d:ab:1f:9e:f5: 13:41:f3:5f:31:a5:c2:40:ea:fa:af:74:bb:95:99: c2:0e:01:88:1e:ce:0a:8c:e4:00:d4:04:3a:d7:bc: 43:b5:b5:69:85:b0:50:71:60:0e:92:27:4a:33:0f: 34:5a:c1:10:cc:f3:4c:80:16:27:50:ba:3d:db:0f: 21:5f:c6:d8:3e:52:04:d5:0b generator: 2 (0x2) Auf Basis dieser beiden Parameter kann nun jede der beiden Parteien ein individuelles Schlüsselpaar erzeugen: einen öffentlichen sowie einen privaten Schlüssel. Beide Kommunikationspartner tauschen ihren öffentlichen Schlüssel über die (bislang unsichere) Leitung aus. Nun können beide Parteien einen zufällig bestimmten (symmetrischen) Schlüssel erzeugen und mit dem öffentlichen Schlüssel des jeweils anderen Partners verschlüsseln und an diesen übermitteln. 10.1 Unterstützung in Libraries und Frameworks 10.1.1 OpenSSL openssl dhparam 10.1.2 Java Cryptography Architecture java.security.AlgorithmParameterGenerator 10.1.3 .NET System.Security.Cryptography.ECDiffieHellmanCng 10.1.4 CryptoAPI / CAPICOM Provider: CAPICOM_PROV_MS_DEF_DSS_DH_PROV 10.2 Best Practices 10.2.1 Diffie-Hellman nur in Verbindung mit einer gegenseitigen Authentisierung Das Problem, die geheimen Schlüssel aus den beiden Nachrichten zu berechnen, in denen die Kommunikationspartner ihr jeweiliges Geheimnis verschlüsselt austauschen, ist praktisch nicht lösbar. Anders verhält es sich im Falle einer Man-in-the-Middle-Attack: Sitzt ein Angreifer zwischen den beiden Kommunikationspartnern, bevor diese ihre öffentlichen Schlüssel austauschen, so kann der Angreifer jede weitere Nachricht zwischen den beiden Partnern lesen, modifizieren und löschen, ohne dass diese etwas bemerken. Aus diesem Grund muss das Diffie-Hellman-Verfahren in Kombination mit einer vorherigen Authentisierung beider Kommunikationspartner angewandt werden (bspw. digitale Signaturen oder Message Authentication Codes). 10.3 Rules of Thumb 10.3.1 Aufwand bei der Berechnung der Diffie-Hellman-Parameter Die Berechnung geeigneter Diffie-Hellman-Parameter ist sehr aufwändig, da eine große, sichere Primzahl ermittelt werden muss. Eine sichere Primzahl ist mind. 1024 bit groß und hat die Form 2p + 1, wobei p wiederum eine Primzahl ist. Bei einer geringen Rechnerauslastung dauert die Suche nach einer geeigneten Primzahl zwischen mehreren Sekunden und einer Minute. Die Berechnung kann daher nicht on-the-fly erfolgen, sondern muss durchgeführt worden sein, lange bevor eine Kommunikationsverbindung auf Basis eines DiffieHellman-Schlüsselaustauschs aufgebaut wird. 11 In-‐Memory-‐Verschlüsselung .NET unterstützt seit Version 2.0 die Verschlüsselung von Daten im Hauptspeicher: • System.Security.SecureString Die Klasse SecureString verschlüsselt vertrauliche Informationen und überschreibt deren Inhalte im Hauptspeicher, unmittelbar nachdem diese nicht mehr benötigt werden. • System.Security.Cryptography.ProtectedMemory System.Security.Cryptography.ProtectedData Die Klassen ProtectedMemory und ProtectedData greifen für die Verschlüsselung sensibler Inhalte auf die betriebssysteminterne Data Protection API (DPAPI) zurück. Entsprechende betriebssysteminterne Aufrufe bietet die CryptoAPI mit den folgenden Funktionen an: • CryptProtectData() • CryptUnprotectData() • CryptProtectMemory() • CryptUnprotectMemory() 12 Salvatorische Klauseln 12.1 Kryptographisch schwache Algorithmen Unterstützt die zugrunde liegende Umgebung, die eingesetzte Software, Framework oder Library keinen kryptographisch sicheren Algorithmus, und ist unter den gegebenen Umständen keine andere Lösung möglich, so sollte eher ein kryptographisch schwacher Algorithmus eingesetzt werden anstatt gänzlich auf die Absicherung zu verzichten. 12.2 Gebot der Vorsicht Sollten die in diesem Dokument als sicher eingestuften und empfohlenen Algorithmen zu einem späteren Zeitpunkt gebrochen werden, so gelten bis zu der nächsten Aktualisierung dieses Dokuments die Empfehlungen des Bundesamts für Sicherheit in der Informatik (BSI) sowie das Gebot der Vorsicht. 13 Abkürzungsverzeichnis 3DES Triple Data Encryption Standard AES Advanced Encryption Standard BF Blowfish CAPICOM Cryptographic Application Programming Interface through Component Object Model CBC Cipher Block Chaining CFB Cipher Feedback Mode CMAC Cipher-based Message Authentication Code CNG Cryptography Next Generation DESede Synonym für 3DES / Triple DES DH Diffie-Hellman DSA Digital Signature Algorithm DSS Digital Signature Standard ECB Electronic Code Book ECDH Elliptic Curve Diffie-Hellman ECDSA Elliptic Curve Digital Signature Algorithm GUID Globally Unique Identifier HMAC key-Hashed Message Authentication Code IV Initialization Vector JCA Java Cryptography Architecture MAC Message Authentication Code MD Message Digest MITM Man-in-the-Middle OFB Output Feedback Mode PBKDF Password-Based Key Derivation Function PGP Pretty Good Privacy PKCS Public Key Cryptography Standards PKI Public Key Infrastructure PRNG Pseudorandom Number Generator RC Rivest Cipher oder Ron's Code RIPEMD RACE Integrity Primitives Evaluation Message Digest RSA Rivest Shamir Adleman SHA Secure Hash Algorithm S/MIME Secure Multipurpose Internet Mail Extension SSL Secure Sockets Layer TLS Transport Layer Security TRNG True Random Number Generator