Sécuriser un mot de passe dans un fichier de propriétés

J’ai une application Java qui se connecte à une firebase database.
Le nom d’utilisateur et le mot de passe de la firebase database sont stockés dans un fichier de propriétés.
Quelle est la pratique courante pour éviter de stocker le mot de passe en clair dans le fichier de propriétés tout en conservant l’option permettant à l’utilisateur de le modifier?
La principale motivation est d’empêcher que quelqu’un regarde par-dessus l’épaule de l’administrateur et voit le mot de passe pendant que l’administrateur édite le fichier de propriétés.
J’ai lu ici qu’il y a un moyen intégré de le faire en C #.
Connaissant java, je ne m’attends pas à trouver une solution intégrée, mais j’aimerais entendre ce que font les autres.
Si je ne trouve pas de bon choix, je vais probablement le chiffrer avec un mot de passe constant qui sera conservé dans le code. Mais je détesterais le faire de cette façon parce que ça ne va pas.

Edit 12th 2012 On dirait qu’il n’y a pas de magie et je dois stocker le mot de passe dans le code ou quelque chose de similaire. À la fin, nous avons mis en place quelque chose de très similaire à ce que Jasypt a mentionné dans l’une des réponses. J’accepte donc la réponse de Jasypt parce que c’est la réponse la plus proche d’une réponse définitive.

entrer la description de l'image ici

Jasypt fournit la classe org.jasypt.properties.EncryptableProperties pour le chargement, la gestion et le déchiffrement transparent des valeurs chiffrées dans les fichiers .properties, ce qui permet de combiner les valeurs chiffrées et non chiffrées dans le même fichier.

http://www.jasypt.org/encrypting-configuration.html

En utilisant un object org.jasypt.properties.EncryptableProperties, une application peut lire et utiliser correctement un fichier .properties comme celui-ci:

datasource.driver=com.mysql.jdbc.Driver datasource.url=jdbc:mysql://localhost/reportsdb datasource.username=reportsUser datasource.password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm) 

Notez que le mot de passe de la firebase database est chiffré (en fait, toute autre propriété peut également être chiffrée, que ce soit en relation avec la configuration de la firebase database ou non).

Comment lit-on cette valeur? comme ça:

 /* * First, create (or ask some other component for) the adequate encryptor for * decrypting the values in our .properties file. */ StandardPBESsortingngEncryptor encryptor = new StandardPBESsortingngEncryptor(); encryptor.setPassword("jasypt"); // could be got from web, env variable... /* * Create our EncryptableProperties object and load it the usual way. */ Properties props = new EncryptableProperties(encryptor); props.load(new FileInputStream("/path/to/my/configuration.properties")); /* * To get a non-encrypted value, we just get it with getProperty... */ Ssortingng datasourceUsername = props.getProperty("datasource.username"); /* * ...and to get an encrypted value, we do exactly the same. Decryption will * be transparently performed behind the scenes. */ Ssortingng datasourcePassword = props.getProperty("datasource.password"); // From now on, datasourcePassword equals "reports_passwd"... 

La solution de compromis des pauvres consiste à utiliser une approche simpliste à signatures multiples.

Par exemple, l’administrateur de firebase database définit le mot de passe de la firebase database des applications sur une chaîne aléatoire de 50 caractères. TAKqWskc4ncvKaJTyDcgAHq82X7tX6GfK2fc386bmNw3muknjU

Il ou elle donne la moitié du mot de passe au développeur de l’application qui le code alors dans le binary Java.

Chaîne privée pass1 = “TAKqWskc4ncvKaJTyDcgAHq82”

L’autre moitié du mot de passe est transmise en tant qu’argument de ligne de commande. l’administrateur de firebase database transmet le message2 à l’assistance système ou à l’administrateur qui entre une heure de début d’application ou la place dans le script de démarrage automatique de l’application.

java -jar /myapplication.jar -pass2 X7tX6GfK2fc386bmNw3muknjU

Lorsque l’application démarre, elle utilise pass1 + pass2 et se connecte à la firebase database.

Cette solution présente de nombreux avantages sans les inconvénients cités.

Vous pouvez sans risque mettre la moitié du mot de passe dans les arguments de la ligne de commande en lisant que cela ne vous aidera pas beaucoup, sauf si vous êtes le développeur qui a l’autre moitié du mot de passe.

L’administrateur de firebase database peut également modifier la seconde moitié du mot de passe et le développeur n’a pas besoin de redéployer l’application.

Le code source peut également être semi-public car il est lu et le mot de passe ne vous donnera pas access à l’application.

Vous pouvez encore améliorer la situation en ajoutant des ressortingctions sur les plages d’adresses IP à partir desquelles la firebase database acceptera les connexions.

Qu’en est-il de la fourniture d’un mécanisme d’authentification N-Factor personnalisé?

Avant de combiner les méthodes disponibles, supposons que nous pouvons effectuer les opérations suivantes:

1) Code dur dans le programme Java

2) Stocker dans un fichier .properties

3) Demander à l’utilisateur de saisir le mot de passe à partir de la ligne de commande

4) Demander à l’utilisateur de saisir le mot de passe d’un formulaire

5) Demander à l’utilisateur de charger un fichier de mot de passe à partir de la ligne de commande ou d’un formulaire

6) Fournir le mot de passe via le réseau

7) de nombreuses alternatives (par exemple, dessiner un secret, empreinte digitale, spécifique à IP, bla bla bla)

1ère option: Nous pourrions rendre les choses plus compliquées pour un attaquant en utilisant l’obscurcissement, mais ceci n’est pas considéré comme une bonne contre-mesure. Un bon codeur peut facilement comprendre comment cela fonctionne s’il peut accéder au fichier. Nous pourrions même exporter un fichier binary par utilisateur (ou simplement la partie obscurcissement ou la partie-clé), de sorte qu’un attaquant doit avoir access à ce fichier spécifique à l’utilisateur, pas à une autre dissortingbution. Encore une fois, nous devrions trouver un moyen de changer les mots de passe, par exemple en recompilant ou en utilisant la reflection pour un comportement de classe de changement à la volée.

2ème option: Nous pouvons stocker le mot de passe dans le fichier .properties dans un format crypté, de sorte qu’il ne soit pas directement visible par un attaquant (comme le fait jasypt ). Si nous avons besoin d’un gestionnaire de mots de passe, nous aurons besoin d’un mot de passe principal qui devrait être stocké quelque part – dans un fichier .class, le fichier de clés, le kernel, un autre fichier ou même en mémoire.
Mais, maintenant, les utilisateurs vont simplement éditer le fichier .properties pour le changement de mot de passe.

3ème option: tapez le mot de passe en cours d’exécution depuis la ligne de commande, par exemple java -jar /myprogram.jar -p sdflhjkiweHIUHIU8976hyd .

Cela ne nécessite pas le mot de passe pour être stocké et restra en mémoire. Cependant, les commandes d’ history et les journaux d’OS peuvent être votre pire ennemi ici. Pour changer les mots de passe à la volée, vous devrez implémenter certaines méthodes (par exemple, écouter les entrées de la console, RMI, les sockets, bla bla bla REST), mais le mot de passe restra toujours en mémoire.

On peut même le déchiffrer temporairement seulement lorsque cela est nécessaire -> puis supprimer le déchiffré, mais toujours garder le mot de passe chiffré en mémoire. Malheureusement, la méthode susmentionnée n’augmente pas la sécurité contre l’access non autorisé en mémoire, car la personne qui y parvient aura probablement access à l’algorithme, au sel et à tout autre secret utilisé.

4ème option: fournissez le mot de passe à partir d’un formulaire personnalisé, plutôt que la ligne de commande. Cela permettra de contourner le problème de la journalisation de l’exposition.

5ème option: fournir un fichier sous la forme d’un mot de passe stocké précédemment sur un autre support -> puis effacer le fichier. Cela contournera à nouveau le problème de l’exposition à la journalisation, et aucune saisie n’est requirejse pour voler l’épaule. Lorsqu’un changement est requirejs, fournissez un autre fichier, puis supprimez-le à nouveau.

6ème option: encore une fois pour éviter le surf épaule, on peut implémenter un appel de méthode RMI, pour fournir le mot de passe (via un canal crypté) à partir d’un autre appareil, par exemple via un téléphone portable. Cependant, vous devez maintenant protéger votre canal réseau et accéder à l’autre périphérique.

Je choisirais une combinaison des méthodes ci-dessus pour atteindre un maximum de sécurité. Il faudrait donc accéder aux fichiers .class, au fichier de propriétés, aux journaux, au canal réseau, à l’épaule, à l’homme au milieu et aux autres fichiers bla bla. Cela peut être facilement mis en œuvre en utilisant une opération XOR entre tous les sous-mots de passe pour produire le mot de passe réel.

Nous ne pouvons pas être protégés contre les access non autorisés en mémoire, cela ne peut être réalisé qu’en utilisant du matériel à access restreint (par exemple, cartes à puce, HSM, SGX), où tout est calculé sans personne, même le propriétaire légitime. capable d’accéder aux clés de déchiffrement ou aux algorithmes. Encore une fois, on peut voler ce matériel aussi, il y a des attaques de canaux latéraux qui peuvent aider les attaquants dans l’extraction de clés et dans certains cas, vous devez faire confiance à une autre partie (avec SGX, par exemple, vous faites confiance à Intel). Bien entendu, la situation risque de s’aggraver lorsque le clonage en enclave sécurisé (désassemblage) sera possible, mais j’imagine que cela prendra quelques années pour être pratique.

En outre, on peut envisager une solution de partage de clés où la clé complète est partagée entre différents serveurs. Cependant, lors de la reconstruction, la clé complète peut être volée. Le seul moyen d’atténuer le problème susmentionné consiste à effectuer un calcul multipartite sécurisé .

Nous devons toujours garder à l’esprit que, quelle que soit la méthode de saisie, nous devons nous assurer que nous ne sums pas vulnérables à la détection de réseau (attaques MITM) et / ou aux enregistreurs de clés.

En fait, il s’agit d’un doublon de Encrypt Password dans les fichiers de configuration? .

La meilleure solution que j’ai trouvée à ce jour réside dans cette réponse: https://stackoverflow.com/a/1133815/1549977

Avantages: Le mot de passe est enregistré dans un tableau de caractères et non sous forme de chaîne. Ce n’est toujours pas bon, mais mieux que tout.