Question

Les fichiers

Java .class peuvent être décompilés assez facilement. Comment puis-je protéger ma base de données si je dois utiliser les données de connexion contenues dans le code?

Était-ce utile?

La solution

Ne codez jamais de mots de passe en dur dans votre code. Cela a été évoqué récemment dans les 25 erreurs de programmation les plus dangereuses :

  

Coder en dur un compte secret et   mot de passe dans votre logiciel est   extrêmement pratique - pour les professionnels   ingénieurs inverses. Si le mot de passe est   la même chose dans tous vos logiciels,   alors chaque client devient vulnérable   quand ce mot de passe devient inévitablement   connu. Et parce que c'est codé en dur,   c'est une douleur énorme à réparer.

Vous devez stocker les informations de configuration, y compris les mots de passe, dans un fichier séparé que l'application lit au démarrage. C’est le seul moyen réel d’empêcher le mot de passe de fuir à la suite de la décompilation (ne le compilez jamais dans le binaire pour commencer).

Pour plus d'informations sur cette erreur courante, vous pouvez lire l'article sur CWE-259 . Cet article contient une définition plus détaillée, des exemples et de nombreuses autres informations sur le problème.

En Java, l’un des moyens les plus simples de procéder consiste à utiliser la classe Preferences. Il est conçu pour stocker toutes sortes de paramètres de programme, dont certains peuvent inclure un nom d'utilisateur et un mot de passe.

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
}

Dans le code ci-dessus, vous pouvez appeler la méthode setCredentials après avoir affiché un dialogue askign pour le nom d'utilisateur et le mot de passe. Lorsque vous devez vous connecter à la base de données, vous pouvez simplement utiliser les méthodes getUsername et getPassword pour récupérer les valeurs stockées. Les identifiants de connexion ne seront pas codés en dur dans vos fichiers binaires, ainsi la décompilation ne posera pas de risque de sécurité.

Remarque importante: les fichiers de préférences sont simplement des fichiers XML au format texte. Assurez-vous de prendre les mesures appropriées pour empêcher les utilisateurs non autorisés d'afficher les fichiers bruts (autorisations UNIX, autorisations Windows, etc.). Sous Linux, du moins, ce n'est pas un problème, car appeler Preferences.userNodeForPackage créera le fichier XML dans le répertoire de base de l'utilisateur actuel, qui de toute façon ne sera pas lisible par d'autres utilisateurs. Sous Windows, la situation peut être différente.

Remarques plus importantes: Les commentaires de cette réponse et d’autres ont fait l’objet de nombreuses discussions sur l’architecture appropriée pour cette situation. La question initiale ne mentionne pas vraiment le contexte dans lequel l'application est utilisée, je vais donc parler des deux situations auxquelles je peux penser. Le premier est le cas dans lequel la personne utilisant le programme connaît déjà (et est autorisée à connaître) les informations d'identification de la base de données. Le second est le cas dans lequel vous, le développeur, essayez de garder les informations d'identification de base de données secrètes vis-à-vis de la personne utilisant le programme.

Premier cas: l'utilisateur est autorisé à connaître les informations d'identification de connexion à la base de données

Dans ce cas, la solution mentionnée ci-dessus fonctionnera. La classe Java Préférences stockera le nom d'utilisateur et le mot de passe en texte brut, mais le fichier de préférences ne sera lisible que par l'utilisateur autorisé. L'utilisateur peut simplement ouvrir le fichier XML de préférences et lire les identifiants de connexion, mais cela ne constitue pas un risque pour la sécurité, car il connaissait d'abord les identifiants.

Deuxième cas: tentative de masquage des informations d'identification de connexion de l'utilisateur

C’est le cas le plus compliqué: l’utilisateur ne doit pas connaître les informations de connexion, mais doit néanmoins accéder à la base de données. Dans ce cas, l'utilisateur qui exécute l'application dispose d'un accès direct à la base de données, ce qui signifie que le programme doit connaître les informations d'identification de connexion à l'avance. La solution que j'ai mentionnée ci-dessus ne convient pas à ce cas. Vous pouvez stocker les identifiants de connexion à la base de données dans un fichier de préférences, mais l'utilisateur pourra lire ce fichier, car

Autres conseils

Placez le mot de passe dans un fichier que l'application lira. NE JAMAIS incorporer des mots de passe dans un fichier source. Période.

Ruby a un module peu connu appelé DBI :: DBRC pour cet usage. Je ne doute pas que Java a un équivalent. Quoi qu’il en soit, il n’est pas difficile d’en écrire un.

Vous écrivez une application web? Si tel est le cas, utilisez JNDI pour le configurer à l'extérieur de l'application. Une vue d'ensemble est disponible ici :

  

JNDI fournit un moyen uniforme pour un   application pour trouver et accéder à distance   services sur le réseau. La télécommande   le service peut être n'importe quel service d'entreprise,   y compris un service de messagerie ou un   service spécifique à l'application, mais   Bien sûr, une application JDBC est   intéressé principalement par une base de données   un service. Une fois qu'un objet DataSource est   créé et enregistré avec un JNDI   service de nommage, une application peut utiliser   l'API JNDI pour accéder à cette source de données   objet, qui peut ensuite être utilisé pour   se connecter à la source de données, il   représente.

Quoi que vous fassiez, les informations sensibles seront stockées quelque part dans un fichier. Votre objectif est de le rendre aussi difficile à obtenir que possible. Tout ce que vous pouvez réaliser dépend de votre projet, de vos besoins et de l’épaisseur du portefeuille de votre entreprise.

Le meilleur moyen est de ne stocker aucun mot de passe, où que ce soit. Pour ce faire, utilisez des fonctions de hachage pour générer et stocker des hachages de mots de passe:

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

Les algorithmes de hachage sont des fonctions à sens unique. Ils tournent n'importe quelle quantité de données   en une "empreinte digitale" de longueur fixe cela ne peut pas être inversé. Ils aussi   avoir la propriété que si l'entrée change même d'un tout petit peu, le   le hachage résultant est complètement différent (voir l'exemple ci-dessus). Ce   est idéal pour protéger les mots de passe, car nous voulons stocker les mots de passe   sous une forme qui les protège même si le fichier de mot de passe lui-même est   compromis, mais en même temps, nous devons être en mesure de vérifier qu'un   le mot de passe de l'utilisateur est correct.

Remarque sans rapport: À l'ancienne époque d'Internet, lorsque vous cliquez sur le lien "mot de passe oublié", les sites Web vous envoyaient par courrier électronique votre mot de passe en texte brut. Ils les stockaient probablement dans une base de données quelque part. Lorsque les pirates informatiques ont accès à leur base de données, ils ont accès à tous les mots de passe. Étant donné que de nombreux utilisateurs utiliseraient le même mot de passe sur plusieurs sites Web, il s’agissait là d’un grave problème de sécurité. Heureusement, ce n'est pas la pratique courante de nos jours.

Vient maintenant la question: quel est le meilleur moyen de stocker des mots de passe? Je considérerais la solution this (du service tempête du service de gestion des utilisateurs et de l'utilisateur) idéal:

  1. Votre utilisateur entre les informations d'identification, qui sont validées par rapport au mot de passe hash
  2. Les hachages de mots de passe sont générés et stockés, pas les mots de passe
  3. Les hachages sont effectués plusieurs fois
  4. Les hachages sont générés à l'aide d'un sel généré de manière aléatoire
  5. Les hachages sont cryptés avec une clé privée
  6. La clé privée est stockée à un endroit physiquement différent du hachage
  7. Les clés privées sont mises à jour temporairement
  8. Les hachages chiffrés sont divisés en fragments
  9. Ces morceaux sont stockés dans des emplacements distincts

Évidemment, vous n’êtes ni Google ni une banque, c’est donc une solution exagérée pour vous. Mais vient ensuite la question: combien de sécurité votre projet nécessite, combien de temps et d’argent vous avez?

Pour de nombreuses applications, bien que cela ne soit pas recommandé, le stockage d'un mot de passe codé en dur dans le code peut constituer une solution suffisante. Toutefois, en ajoutant facilement quelques étapes de sécurité supplémentaires à partir de la liste ci-dessus, vous pouvez rendre votre application beaucoup plus sécurisée.

Par exemple, supposons que l’étape 1 ne soit pas une solution acceptable pour votre projet. Vous ne voulez pas que les utilisateurs entrent un mot de passe à chaque fois, ou vous ne voulez même pas / n'avez pas besoin que les utilisateurs connaissent le mot de passe. Vous avez toujours des informations sensibles quelque part et vous souhaitez les protéger. Vous avez une application simple, il n’ya pas de serveur pour stocker vos fichiers ou c’est trop compliqué pour votre projet. Votre application s'exécute dans des environnements où il n'est pas possible de stocker des fichiers de manière sécurisée. C’est l’un des cas les plus graves, mais avec une mesure de sécurité supplémentaire, vous pouvez obtenir une solution beaucoup plus sûre. Par exemple, vous pouvez stocker les informations sensibles dans un fichier et le chiffrer. Vous pouvez avoir la clé privée de chiffrement codée en dur dans le code. Vous pouvez masquer le code, ce qui rend un peu plus difficile pour quelqu'un de le déchiffrer. Il existe de nombreuses bibliothèques à cet effet, voir ce lien . (Je tiens à vous avertir une fois de plus que ce n’est pas sûr à 100%. Un pirate informatique intelligent disposant des connaissances et des outils adéquats peut pirater cela. Mais

Cette question montre comment stocker les mots de passe et autres données dans un fichier crypté: Cryptage basé sur un mot de passe Java 256 bits AES

MD5 est un algorithme de hachage, pas un algorithme de chiffrement. En bref, vous ne pouvez pas revenir en arrière, vous ne pouvez que comparer. Il devrait idéalement être utilisé lors du stockage des informations d'authentification de l'utilisateur et non de son nom d'utilisateur et de son mot de passe. Le nom d'utilisateur et le pwd de la base de données doivent être chiffrés et conservés dans un fichier de configuration, pour le moins.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top