© Creative Thoughts/Shutterstock.com
Teil 1: Symmetrische Verschlüsselung

Rubinrote Sicherheit


Sicherheit geht vor – das gilt auch in Ruby. Das Bauchgefühl kann jedoch trügen, wenn es um sichere Lösungen geht. Darum lohnt es sich, die zur Verfügung stehenden Optionen einmal genauer unter die Lupe zu nehmen.

Die Standard-Library in Ruby bietet mit dem OpenSSL-Modul ein leistungsfähiges Interface zum Verschlüsseln. Wie der Name schon andeutet, handelt es sich hierbei um einen Wrapper der nativen OpenSSL Library, garniert mit dem syntaktischen Zucker, den die Programmiersprache von Haus aus mitbringt.

Auf OpenSSL als De-facto-Standard bei Kryptographie im Open-Source-Bereich zu setzen, ist natürlich naheliegend – es birgt aber auch einige Gefahren. OpenSSL versteht sich als ein Werkzeugkasten für kryptographische Algorithmen und legt seinen Fokus auf Vollständigkeit, was jedoch zur Folge hat, dass es eine Vielzahl von Optionen mit sich bringt, die nach aktuellsten Kriterien leider nicht immer alle als sicher gelten. Man ist als Entwickler deshalb dazu verdammt, unter der Vielzahl der Optionen diejenigen herauszupicken, die für den jeweiligen Anwendungsfall passen und dabei so sicher wie möglich sind.

Dies ist natürlich nicht immer einfach und deshalb möchte ich Ihnen konkret zum Thema Verschlüsselung einen Überblick verschaffen, was es aus historischer Sicht an Möglichkeiten gab und gibt, was die Nachteile sind, wie sich die Dinge weiterentwickelt haben und wie Stand heute eine moderne Verschlüsselung aussieht, die Sie dann auch in Ihren Projekten einsetzen können und sollten.

Es gibt zwei prominente Ansätze, um symmetrische Verschlüsselung zu betreiben: den Stream Cipher [1] und den Block Cipher [2]. Beides sind Varianten, die mit unterschiedlichen Ansätzen sichere Verschlüsselungsverfahren liefern können. Wir konzentrieren uns vorerst auf die Stream Cipher, die in ihrer Konstruktion einfacher sind, bevor wir uns den komplexeren Block Ciphern widmen.

Was bedeutet „sicher“ im Kontext von Verschlüsselung?

Wer kennt das nicht? Der Chef verlangt, dass wir aufgrund von erhöhten Sicherheitsanforderungen bestimmte Daten verschlüsseln sollen, damit das Ganze „sicher“ wird. Alle Beteiligten nicken daraufhin eifrig, aber bei den Armen, die das dann ausbaden – sprich implementieren – sollen, macht sich schnell ein ungutes Gefühl breit, weil sich eigentlich keiner so sicher ist, was „sicher“ in diesem Zusammenhang wirklich bedeutet. Tatsächlich ist es schwierig, das allumfassend für Software zu definieren, da es natürlich vom Kontext, den Anforderungen und den möglichen Risiken abhängt. Für die Theorie ist aber ein Bauchgefühl keine gute Grundlage, denn die theoretische Erforschung und Bewertung von Kryptographie kann nur gelingen, wenn man auf einem soliden Fundament aufbaut.

Da wir dazu erzogen werden, die Schlüssel beim Verschlüsseln geheim zu halten, ist man dazu verleitet, den Sicherheitsbegriff vor allem an diesen festzumachen. Man muss sich aber immer vor Augen halten, dass die Schlüssel immer nur ein Werkzeug und ein Mittel zum Zweck sind, denn in Wahrheit hat die oberste Priorität immer die Nachricht selbst. Sie ist es, die wir in erster Linie schützen wollen, nicht die Schlüssel. Diese helfen uns lediglich auf dem Weg dahin. Von dieser Prämisse ausgehend definiert man Sicherheit in der Verschlüsselung so, dass ein Verfahren dann als sicher gilt, wenn man aus alleiniger Kenntnis des Ciphertexts keinerlei Informationen, nicht mal partielle, über den zugrunde liegenden Plaintext gewinnen kann [3]. Umgekehrt bedeutet dies, dass man folglich noch nicht einmal zwangsläufig den Ciphertext entschlüsseln muss, sondern jeder noch so winzige Informationsgewinn über den Plaintext bereits ausreicht, um ein Verfahren zu brechen. Salopp formuliert: Die Kenntnis des Ciphertexts bringt einem keine zusätzlichen Informationen über den Plaintext. Man ist mit oder ohne genau so schlau wie vorher. Der Ausschluss des Informationsgewinns hat allerdings eine Ausnahme: Man lässt die Kenntnis über die Länge des Plaintexts zu, das heißt, dass die einzige Information, die man einem potenziellen Angreifer zugesteht, diejenige ist, dass er herausfinden kann, wie lange der ursprüngliche Plaintext ist. Dies ist in erster Linie eine technische Einschränkung, weil es mit erheblichem Aufwand verbunden ist, die Länge des Plaintexts zu verschleiern. Wenn ein Verfahren diese Anforderungen erfüllt, spricht man davon, dass die Verschlüsselung Perfect Secrecy [4] genügt.

Das One-Time Pad

Ein solches, bereits seit Langem bekanntes Verfahren ist das One-Time Pad [5]. Seine Konstruktion ist geradezu simpel. Hat man eine Nachricht m der Länge n, so benötigt man einen zufällig generierten Schlüssel, der ebenfalls die Länge n besitzt. Hat also m z. B. 100 Bytes Länge, so generiert man 100 zufällige Bytes als Schlüssel. Die Verschlüsselung c ist dann definiert als:

c := m ⊕ k

Wobei "⊕" XOR, Bit für Bit bzw. Byte für Byte, bedeutet. Die entsprechende Entschlüsselung ist ähnlich einfach definiert:

m := c ⊕ k

Im Grunde genommen ist es dieselbe Operation, es wird in beiden Fällen ein XOR mit dem Schlüssel durchgeführt. Dass dies tatsächlich das gewünschte Ergebnis, nämlich die ursprüngliche Nachricht, liefert, sieht man, wenn man c ersetzt:

c ⊕ k = m ⊕ k ⊕ k = m ⊕ (k ⊕ k) = m ⊕ 0 = m

Man nutzt aus, dass XOR assoziativ ist und dass „XOR mit sich selbst“ lauter Nullen ergibt und XOR mit lauter Nullen keine Änderung herbeiführt. Es kommt zum Schluss also tatsächlich wieder die ursprüngliche Nachricht zum Vorschein.

Das One-Time Pad lässt sich einfach in Ruby [6] nachbauen, wie Listing 1 zeigt.

Listing 1

require 'securerandom' require_relative 'string_refinements' using StringRefinements module OneTimePad def encrypt(data, pad) data.xor(pad) end alias_method :decrypt, :encrypt module_function :encrypt, :decrypt end data = "Attack at dawn" pad = SecureRandom.bytes(data.size) encrypted = OneTimePad.encrypt(data, pad) # Zufällig, aber i...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang