Frage

Java .class Dateien können ziemlich leicht dekompiliert werden. Wie kann ich meine Datenbank schützen, wenn ich die Login-Daten im Code verwenden?

War es hilfreich?

Lösung

Nie hart Code Passwörter in Ihren Code. Dies wurde kürzlich in den Top 25 Most Dangerous Programming Fehler gebracht :

  

Hard-Codierung ein geheimes Konto und   Passwort in Ihre Software   extrem komfortabel - für geübte   Reverse-Ingenieure. Wenn das Passwort   das gleiche für alle Ihre Software,   dann wird jeder Kunde verwundbar   wenn das Passwort unvermeidlich wird   bekannt. Und weil es hart codiert,   es ist ein riesiger Schmerz zu beheben.

Sie sollten Konfigurationsinformationen speichern, einschließlich Passwörter, in einer separaten Datei, die die Anwendung liest, wenn es beginnt. Das ist die einzige wirkliche Möglichkeit, das Passwort aus undichtem als Folge der Dekompilierung zu verhindern (es nie in die binären kompilieren zu beginnen).

Weitere Informationen zu dieser gemeinsamen Fehler, können Sie die CWE-259 Artikel lesen . Der Artikel enthält eine gründlichere Definition, Beispiele und viele andere Informationen über das Problem.

In Java ist eine der einfachsten Möglichkeiten, dies zu tun ist, um die Vorlieben Klasse zu verwenden. Es ist für alle Arten von Programmeinstellungen zu speichern, von denen einige einen Benutzernamen und ein Passwort enthalten könnte.

import java.util.prefs.Preferences;

public class DemoApplication {
  Preferences preferences = 
      Preferences.userNodeForPackage(DemoApplication.class);

  public void setCredentials(String username, String password) {
    preferences.put("db_username", username);
    preferences.put("db_password", password);
  }

  public String getUsername() {
    return preferences.get("db_username", null);
  }

  public String getPassword() {
    return preferences.get("db_password", null);
  }

  // your code here
}

In dem obigen Code könnten Sie die setCredentials Methode aufrufen, nachdem ein Dialog askign für den Benutzernamen und das Kennwort zeigt. Wenn Sie in der Datenbank verbinden, dann können Sie nur die getUsername und getPassword Methoden verwenden, um die gespeicherten Werte abzurufen. Die Anmeldedaten werden nicht hartcodiert in den Binärdateien sein, so Dekompilierung nicht ein Sicherheitsrisiko darstellen.

Wichtiger Hinweis: Die Einstellungsdateien sind einfach nur Text-XML-Dateien. Stellen Sie sicher, dass Sie geeignete Maßnahmen, um nicht autorisierte Benutzer zu verhindern, dass gerade die Raw-Dateien (UNIX-Berechtigungen, Windows-Berechtigungen, etc.). In Linux, zumindest ist dies kein Problem, weil Preferences.userNodeForPackage Aufruf wird die XML-Datei in der aktuellen Benutzer-Home-Verzeichnis erstellen, die von anderen Benutzern sowieso nicht lesbar ist. In Windows kann die Situation anders sein.

Mehr Wichtige Hinweise: Es hat sich in den Kommentaren dieser Antwort und andere viel diskutiert worden über das, was die richtige Architektur für diese Situation ist. Die ursprüngliche Frage nicht erwähnt, wirklich den Kontext, in dem die Anwendung verwendet wird, also werde ich über die beiden Situationen sprechen ich denken kann. Der erste ist der Fall, in dem die Person, die das Programm bereits kennt (und ist berechtigt, zu wissen), um die Datenbank-Anmeldeinformationen. Der zweite ist der Fall, in dem Sie die Entwickler, versuchen, die Datenbank-Anmeldeinformationen geheim von der Person zu halten das Programm verwenden.

Erster Fall: Der Nutzer ist berechtigt, die Datenbank-Anmeldeinformationen zu wissen,

In diesem Fall ist die Lösung, die ich oben erwähnt wird funktionieren. Die Java Preference Klasse die Benutzername und das Passwort im Klartext, aber die Voreinstellungsdatei wird nur von dem berechtigten Benutzer lesbar gespeichert. Der Benutzer kann einfach die Datei Einstellungen XML öffnen und die Anmeldeinformationen lesen, aber das ist nicht ein Sicherheitsrisiko dar, da der Benutzer die Anmeldeinformationen wußte zu beginnen.

Zweiter Fall: Der Versuch, Anmeldeinformationen von dem Benutzer zu verbergen anmelden

Dies ist komplizierter Fall: der Benutzer die Anmeldedaten wissen sollten, muss aber noch Zugriff auf die Datenbank. In diesem Fall hat der Benutzer die Anwendung ausgeführt direkten Zugriff auf die Datenbank, was bedeutet, das Programm der Login-Daten im voraus zu wissen braucht. Die Lösung, die ich oben erwähnt ist für diesen Fall nicht geeignet. Sie können die Datenbank-Anmeldeinformationen in einer Einstellungsdatei speichern, aber er Benutzer diese Datei lesen können, da sie der Besitzer sein. Eigentlich,gibt es wirklich keine gute Möglichkeit, diesen Fall in einer sicheren Art und Weise zu nutzen.

Correct Fall: eine Multi-Tier-Architektur mit

Der richtige Weg, es zu tun ist, eine mittlere Schicht zu haben, zwischen dem Datenbankserver und Client-Anwendung, die einzelnen Benutzer authentifiziert und ermöglicht eine begrenzte Anzahl von Operationen durchgeführt werden. Jeder Nutzer würden ihre eigenen Login-Daten haben, aber nicht für den Datenbankserver. Die Anmeldeinformationen würden Zugriff auf die Mittelschicht (die Geschäftslogikebene) erlauben und wäre für jeden Benutzer unterschiedlich sein.

Jeder Nutzer würden ihre eigenen Benutzernamen und ein Passwort haben, die ohne Sicherheitsrisiko lokal in einer Einstellungsdatei gespeichert werden könnten. Dies ist ein dreischichtigen Architektur genannt (die Ebene des Datenbankserver zu sein, Business-Logik-Server und Client-Anwendung). Es ist komplexer, aber es ist wirklich der sicherste Weg, um diese Art der Sache zu tun.

Die grundlegende Reihenfolge der Operationen ist:

  1. authentifiziert Clients mit Geschäftslogikebene mit dem persönlichen Benutzernamen / Passwort des Benutzers. Der Benutzername und das Passwort für den Benutzer bekannt und werden nicht auf die Datenbank-Anmeldeinformationen in irgendeiner Weise mit.
  2. Wenn die Authentifizierung erfolgreich ist, macht der Kunde die Geschäftslogikebene eine Anfrage nach Informationen aus der Datenbank zu fragen. Zum Beispiel kann ein Inventar von Produkten. Beachten Sie, dass die Anforderung des Clients ist keine SQL-Abfrage; es ist ein Remoteprozeduraufruf wie getInventoryList.
  3. Die Geschäftslogikebene eine Verbindung zur Datenbank und ruft die angeforderten Informationen. Die Geschäftslogikebene ist verantwortlich für eine sichere SQL-Abfrage bildet, basierend auf der Anforderung des Benutzers. Alle Parameter, um die SQL-Abfrage hygienisiert werden sollten, SQL-Injection-Angriffe zu verhindern.
  4. Die Geschäftslogikebene sendet die Inventarliste zurück an die Client-Anwendung.
  5. Der Client zeigt die Inventarliste für den Benutzer.

Beachten Sie, dass in dem gesamten Prozess, nie die Client-Anwendung direkt mit der Datenbank verbindet . Die Geschäftslogikebene empfängt eine Anforderung von einem authentifizierten Benutzer, verarbeitet die Anforderung des Clients für eine Inventarliste, und nur führt dann eine SQL-Abfrage.

Andere Tipps

Setzen Sie das Kennwort in einer Datei, die die Anwendung lesen. Nie einbetten Passwörter in einer Quelldatei. Period.

Ruby hat eine wenig bekannte Modul namens DBI :: DBRC für eine solche Nutzung. Ich habe keinen Zweifel daran, dass Java eine gleichwertige hat. Wie auch immer, es ist nicht schwer, einen zu schreiben.

Schreibst du eine Web-Anwendung? Wenn ja, verwendet JNDI zu konfigurieren extern an die Anwendung. Eine Übersicht finden Sie hier rel="nofollow:

  

JNDI bietet eine einheitliche Art und Weise für eine   Anwendung und den Zugang zu finden Fern   Dienste über das Netzwerk. Die Fernbedienung   Service kann jedes Unternehmen Service,   einschließlich eines Messaging-Dienst oder   applikationsspezifische Service, sondern von   Natürlich eine JDBC-Anwendung ist   interessiert vor allem in einer Datenbank   Bedienung. Sobald ein Datasource-Objekt ist   erstellt und mit einem JNDI registriert   Service zu nennen, kann eine Anwendung verwenden   der JNDI-API, die Datasource zugreifen   Gegenstand, der sein kann dann verwendet   verbindet es mit der Datenquelle   darstellt.

Egal, was Sie tun, wird die sensible Informationen in irgendeiner Datei irgendwo gespeichert werden. Ihr Ziel ist es so schwer zu bekommen wie möglich zu machen. Wie viel davon Sie erreichen können, hängt von Ihrem Projekt, Bedürfnisse und Dicke Ihres Unternehmens Brieftasche.

Der beste Weg ist keine Passwörter überall zu speichern. Dies wird durch Hash-Funktionen erreicht zu generieren und zu speichern Passwort-Hashes:

hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366
  

Hash-Algorithmen sind eine Möglichkeit, Funktionen. Sie drehen sich jede Menge Daten   in eine feste Länge „Fingerabdruck“, der nicht rückgängig gemacht werden kann. Sie auch   haben die Eigenschaft, dass, wenn die Eingabe von selbst ein klein wenig verändert, die   Hash resultierende ist völlig anders (das Beispiel oben). Diese   ist für Passwörter zu schützen, weil wir Passwörter gespeichert werden sollen   in einer Form, die sie selbst dann, wenn die Passwort-Datei selbst schützt, ist   kompromittiert, aber zur gleichen Zeit, müssen wir in der Lage sein, dass ein, um zu überprüfen   Benutzer-Passwort korrekt ist.

Unrelated Anmerkung: In den alten Tagen des Internets, wenn Sie auf 'Details vergessen' Link, Websites würden Sie Ihr Klartext-Passwort per E-Mail. Sie wurden wahrscheinlich irgendwo die in einer Datenbank zu speichern. Wenn Hacker Zugriff auf ihre Datenbank gewonnen, würden sie den Zugriff auf alle Passwörter gewinnen. Da viele Benutzer das gleiche Passwort in mehreren Websites verwenden würden, war dies ein riesiges Sicherheitsproblem. Zum Glück, heute ist dies nicht die gängige Praxis.

Jetzt kommt die Frage: Was ist der beste Weg, Passwörter zu speichern? Ich würde dies (Authentifizierung und Benutzerverwaltung Dienst stormpath) Lösung ein verdammt ideal ein:

  1. Ihre Benutzer gibt die Anmeldeinformationen, und dies gegen die validierte Passwort-Hash
  2. Passwort-Hashes erzeugt und gespeichert werden, keine Passwörter
  3. Hashes werden mehrfach durchgeführt
  4. Hashes sind eine zufällig erzeugte Salz erzeugt mit
  5. Hashes sind mit einem privaten Schlüssel verschlüsselt
  6. Private Key an einem physikalisch anderen Ort als Hashes gespeichert
  7. Private Schlüssel sind auf eine zeitbasierten Art und Weise aktualisiert
  8. Encrypted Hashes sind unterteilt in Stücke
  9. Diese Stücke in physikalisch getrennten Orten gespeichert

Offensichtlich sind Sie nicht die Google oder eine Bank, so ist dies eine Overkill Lösung für Sie. Aber dann kommt die Frage: Wie viel Sicherheit Ihr Projekt erfordert, wie viel Zeit und Geld, das Sie haben?

Für viele Anwendungen, obwohl nicht empfohlen, das Speichern hartcodierte Kennwort im Code könnte eine gute genug Lösung sein. Doch durch einige zusätzliche Schritte der Sicherheit aus der obigen Liste leicht hinzufügen, können Sie Ihre Anwendung viel sicherer machen.

Zum Beispiel, lassen Sie uns Schritt annehmen 1 keine akzeptable Lösung für Ihr Projekt sein. Sie wollen nicht, Benutzer-Passwort, jedes Mal eingeben oder Sie haben nicht einmal wollen / müssen die Benutzer das Passwort kennen. Noch haben Sie irgendwo sensible Informationen, und Sie wollen, dass diese zu schützen. Sie haben eine einfache Anwendung, gibt es keinen Server Ihre Dateien zu speichern oder ist dies zu viel Aufwand für Ihr Projekt. Ihre Anwendung läuft auf Umgebungen, in denen es nicht möglich ist, Dateien sicher gespeichert zu haben. Dies ist eines der schlimmsten Fall, aber immer noch mit einigen zusätzlichen Sicherheitsmaßnahme können Sie viel sicherere Lösung. Zum Beispiel können Sie die sensiblen Daten in einer Datei speichern, und Sie können die Datei verschlüsseln. Sie können die Verschlüsselung privaten Schlüssel hart im Code codiert haben. Sie können den Code verschleiern, so dass Sie machen es ein bisschen schwieriger für jemanden, der es zu knacken. Es gibt viele Bibliotheken gibt es für diesen Zweck finden Sie unter diesen Link . (Ich möchte Sie warnen, ein weiteres Mal, dass dies nicht zu 100% sicher ist. Ein intelligenter Hacker mit richtigen Wissen und Werkzeuge können diese hacken. Aber Basisd auf Ihren Anforderungen und Bedürfnissen, könnte dies eine gute genug Lösung für Sie sein).

Diese Frage zeigt, wie Passwörter und andere Daten in einer verschlüsselten Datei gespeichert werden: Java 256-Bit-AES-Kennwortbasierte Verschlüsselung

MD5 ist ein Hash-Algorithmus, nicht ein Verschlüsselungsalgorithmus, kurz gesagt u zurück wat cant get u gehasht, kann u nur vergleichen. Es sollte idealerweise verwendet werden, wenn die Benutzer-Authentifizierungsinformationen und nicht db Benutzernamen und ein Passwort zu speichern. db Benutzername und PWD verschlüsselt werden sollen und in einer Konfigurationsdatei, die am wenigsten zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top