Germany/Projekte/Top 10 fuer Entwickler-2013/A6-Verlust der Vertraulichkeit sensibler Daten

A7 Kryptografisch unsichere Speicherung
Jeder Benutzer des Systems ist zu betrachten. Haben diese ein Interesse, auf geschützte Daten unberechtigt zuzugreifen? Wie steht es um Administratoren? Angreifer brechen üblicherweise nicht die eigentliche Kryptografie. Statt dessen finden Sie Schlüssel, Klartexte oder greifen über Kanäle mit automatischer Entschlüsselung auf Daten zu. Fehlende Verschlüsselung vertraulicher Daten ist die häufigste Schwachstelle, gefolgt von unsicherer Schlüsselerzeugung, der Speicherung statischer Schlüssel und die Nutzung schwacher Algorithmen. Schwache Hashwerte ohne Salt kommen zum Passwortschutz oft vor. Ein ein-geschränkter Zugriff lässt externe Angreifer solche Probleme i.d.R. nicht leicht ent-decken. Den nötigen Zugriff müssen sie vorher auf andere Weise erlangen. Fehler kompromittieren regelmäßig vertrauliche Daten. Es handelt sich hierbei oft um sensitive Daten wie personenbezogene Daten, Benutzernamen und Passwörter oder Kreditkarteninformationen. Betrachten Sie den Wert verlorener Daten und die Auswirkungen auf die Reputation des betroffenen Unternehmens. Hat es ggf. auch juristische Konsequenzen, wenn die Daten bekannt werden?

 Szenario 1 : Eine Anwendung speichert verschlüsselt Kreditkartendaten in einer Datenbank, um Sie vor Angreifern zu schützen. Die Datenbank ist so eingerichtet, dass die Daten beim Auslesen automatisch entschlüsselt werden. Durch SQL-Injection können in diesem Fall alle Kreditkartendaten im Klartext ausgelesen werden. Das System hätte so konfiguriert sein sollen, dass nur nachgelagerte Anwendungen und nicht die Webanwendung selbst entschlüsseln dürfen.  Szenario 2 : Ein Datensicherungsband speichert verschlüsselte Gesundheitsdaten, aber der Schlüssel ist ebenfalls dort gespeichert. Das Band geht auf dem Transportweg verloren.  Szenario 3 : Die Passwortdatenbank benutzt Hashwerte ohne Salt zur Speicherung der Passwörter. Eine Schwachstelle in der Downloadfunktion ermöglicht einem Angreifer den Zugriff auf die Datei. Zu allen Hashes kann in vier Wochen ein passender Klartext gefunden werden. Bei starken Hashwerten mit Salt hätte dieser Angriff über 3000 Jahre gedauert.

Eine Übersicht über alle Tücken unsicherer Kryptografie liegt weit außerhalb des Rahmens der Top 10. Für alle vertrau-lichen Daten sollten Sie zumindest:
 * 1) Die Bedrohungen betrachten, vor denen Sie die Daten schützen wollen (z. B. Innen- und Außentäter) und sicherstellen, dass diese Daten angemessen durch Verschlüsselung geschützt werden.
 * 2) Sicherstellen, dass ausgelagerte Datensicherungen verschlüsselt sind und die Schlüssel getrennt verwaltet und gesichert werden.
 * 3) Sicherstellen, dass angemessene, starke Algorithmen und Schlüssel verwendet und verwaltet werden.
 * 4) Sicherstellen, dass Passwörter mit einem starken Algorithmus und einem angemessenen Salt gehasht werden.
 * 5) Sicherstellen, dass alle Schlüssel und Passwörter vor unberechtigtem Zugriff geschützt sind.

= JAVA =

Beispiel für das sichere Hashen von Passwörtern. Um die Sicherheit zu erhöhen sollte jedes Passwort mit einem Zufallswert (Salt) berechnet und möglichst viele Iterationen beim Hashing (> 10.000) genutzt werden.

String password = "Password"; byte[] salt = new byte[8]; (new SecureRandom).nextBytes(salt); MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.reset; digest.update(salt); byte[] input = digest.digest(password.getBytes("UTF-8")); for (int i = 0; i < iterations; i++) { digest.reset; input = digest.digest(input); }

Einfaches Beispiel für die Veschlüsselung von Texten, hier mit dem AES-128 Algorithmus. Die Wahl von Algorithmus und Schlüssellänge kommt immer auf die jeweiligen Daten und die Anwendung an. Der Schlüssel selbst sollte natürlich nie wie hier im Code selbst stehen sondern getrennt von Anwendung und verschlüsselten Daten für andere unzugänglich abgelegt werden. Dafür empfiehlt sich eine Schlüsseldatei (z.B. Java Keystore), die ihrerseits über einen MasterKey für andere unzugänglich gemacht werden sollte:

byte[] ivBytes = new byte[16]; (new SecureRandom).nextBytes(ivBytes); SecretKeySpec key = new SecretKeySpec("My128bitMastrKey".getBytes, "AES"); IvParameterSpec paramSpec = new IvParameterSpec(ivBytes); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); byte[] encrypted = cipher.doFinal(plainText.getBytes);

Grundsätzlich kommt es bei der Verschlüsselung neben der richtigen Wahl des Algorithmus und der Parameter (wie Schlüssellänge oder Cipher-modus) auch auf das richtige Schlüsselmanagement an. Die Benutzung der ESAPI erleichtert dabei die Handhabung ungemein, da neben einer grossen Bandbreite an Verschlüsselungs-, Hash-, und Signaturalgorithmen auch Methoden für die Schlüsselerzeugung -und Verwaltung untersützt werden. Die Verschlüsslung eines Textes beispielsweise reduziert sich dann zu:

CipherText ciphertext = ESAPI.encryptor.encrypt( new PlainText(myplaintext) );

Einen umfangreicheren Überblick über die Anforderungen und die hierbei zu vermeidenden Probleme gibt es unter ASVS requirements on Cryptography (V7). Des Weiteren:
 * OWASP Top 10-2007 on Insecure Cryptographic Storage
 * ESAPI Encryptor API
 * OWASP Development Guide: Chapter on Cryptography
 * OWASP Code Review Guide: Chapter on Cryptography


 * CWE Entry 310 on Cryptographic Issues
 * CWE Entry 312 on Cleartext Storage of Sensitive Information
 * CWE Entry 326 on Weak Encryption

= Test =

tbd Text

tbd Text

tbd Text

(ganze Breite) Text