J'ai un script python qui crée une connexion ODBC. La connexion ODBC est générée avec une chaîne de connexion. Dans cette chaîne de connexion, je dois inclure le nom d'utilisateur et le mot de passe pour cette connexion.
Existe-t-il un moyen simple de masquer ce mot de passe dans le fichier (juste que personne ne puisse le lire lorsque je modifie le fichier)?
Le codage Base64 est dans la bibliothèque standard et fera pour arrêter les surfeurs à l'épaule:
>>> import base64
>>> print base64.b64encode("password")
cGFzc3dvcmQ=
>>> print base64.b64decode("cGFzc3dvcmQ=")
password
Douglas F Shearer's est la solution généralement approuvée sous Unix lorsque vous devez spécifier un mot de passe pour une connexion à distance.
Vous ajoutez une option --password-from-file pour spécifier le chemin et lire le texte en clair dans un fichier.
Le fichier peut alors se trouver dans la zone protégée par le système d'exploitation de l'utilisateur . Il permet également à différents utilisateurs de sélectionner automatiquement leur propre fichier.
Pour les mots de passe que l'utilisateur du script n'est pas autorisé à connaître, vous pouvez exécuter le script avec une autorisation spécifique et attribuer le fichier de mot de passe à cet utilisateur root/admin.
Voici une méthode simple:
Cela devrait être un peu plus sécurisé que le décodage en base64 - bien qu'il soit vulnérable à un décompilateur py_to_pyc.
Si vous travaillez sur un système Unix, utilisez le module netrc de la bibliothèque Python standard. Il lit les mots de passe dans un fichier texte séparé (.netrc), dont le format est décrit here .
Voici un petit exemple d'utilisation:
import netrc
# Define which Host in the .netrc file to use
Host = 'mailcluster.loopia.se'
# Read from the .netrc file in your home directory
secrets = netrc.netrc()
username, account, password = secrets.authenticators( Host )
print username, password
La meilleure solution, en supposant que le nom d'utilisateur et le mot de passe ne puissent pas être fournis au moment de l'exécution par l'utilisateur, est probablement un fichier source séparé contenant uniquement l'initialisation de variable pour le nom d'utilisateur et le mot de passe importés dans votre code principal. Ce fichier n'aurait besoin d'être édité que lorsque les informations d'identification changent. Sinon, si vous ne vous inquiétez que des surfeurs à l'épaule avec des mémoires moyennes, l'encodage en base 64 est probablement la solution la plus simple. ROT13 est trop facile à décoder manuellement, n’est pas sensible à la casse et conserve trop de signification dans son état crypté. Encodez votre mot de passe et votre identifiant utilisateur en dehors du script python. Avoir le script décoder au moment de l'exécution pour une utilisation.
Donner des identifiants de scripts pour des tâches automatisées est toujours une proposition risquée. Votre script doit avoir ses propres informations d'identification et le compte qu'il utilise ne doit avoir d'autre accès que celui qui est nécessaire. Au moins, le mot de passe devrait être long et plutôt aléatoire.
Que diriez-vous d'importer le nom d'utilisateur et le mot de passe depuis un fichier externe au script? De cette façon, même si quelqu'un se procurait le script, le mot de passe ne serait pas automatiquement obtenu.
base64 est la solution idéale pour vos besoins simples. Il n'est pas nécessaire d'importer quoi que ce soit:
>>> 'your string'.encode('base64')
'eW91ciBzdHJpbmc=\n'
>>> _.decode('base64')
'your string'
C'est un problème assez commun. En règle générale, le mieux que vous puissiez faire est de
A) créez une sorte de fonction de chiffrement Ceasar pour encoder/décoder (mais pas pour autant rot13) Ou B) la méthode recommandée consiste à utiliser une clé de cryptage, à la portée de votre programme, pour encoder/décoder le mot de passe. Dans lequel vous pouvez utiliser la protection de fichier pour protéger l'accès à la clé . Sur ces lignes, si votre application fonctionne en tant que service/démon (comme un serveur Web), vous pouvez placer votre clé dans un magasin de clés protégé par mot de passe avec la saisie du mot de passe lors du démarrage du service. Il faudra un administrateur pour redémarrer votre application, mais vous aurez une très bonne protection pour vos mots de passe de configuration.
Une approche plus locale plutôt que de convertir les authentifications/mots de passe/noms d'utilisateur en détails chiffrés.FTPLIBest juste l'exemple . " pass.csv " est le nom du fichier csv
Enregistrez le mot de passe au format CSV comme ci-dessous:
nom d'utilisateur
mot de passe de l'utilisateur
(Sans en-tête de colonne)
Lecture du fichier CSV et enregistrement dans une liste.
Utilisation de List elelments en tant que détails d'authentification.
Code complet.
import os
import ftplib
import csv
cred_detail = []
os.chdir("Folder where the csv file is stored")
for row in csv.reader(open("pass.csv","rb")):
cred_detail.append(row)
ftp = ftplib.FTP('server_name',cred_detail[0][0],cred_detail[1][0])
pour python3 obfuscation à l'aide de base64
se fait différemment:
import base64
base64.b64encode(b'PasswordStringAsStreamOfBytes')
qui se traduit par
b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM='
notez la représentation informelle de la chaîne, la chaîne réelle est entre guillemets
et décodage à la chaîne d'origine
base64.b64decode(b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=')
b'PasswordStringAsStreamOfBytes'
pour utiliser ce résultat lorsque des objets chaîne sont requis, l'objet bytes peut être traduit
repr = base64.b64decode(b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=')
secret = repr.decode('utf-8')
print(secret)
pour plus d'informations sur la manière dont python3 gère les octets (et les chaînes en conséquence), veuillez consulter le documentation officielle .
Votre système d'exploitation fournit probablement des installations pour chiffrer les données en toute sécurité. Par exemple, sous Windows, il y a DPAPI (API de protection des données). Pourquoi ne pas demander à l'utilisateur ses identifiants la première fois que vous exécutez, puis les chiffrer à l'écart pour les exécutions suivantes?
Placez les informations de configuration dans un fichier de configuration chiffré. Interrogez cette information dans votre code à l'aide d'une clé. Placez cette clé dans un fichier séparé par environnement et ne la stockez pas avec votre code.
Si vous utilisez Windows, vous pouvez utiliser la bibliothèque win32crypt. Il permet le stockage et la récupération des données protégées (clés, mots de passe) par l'utilisateur qui exécute le script. Ainsi, les mots de passe ne sont jamais stockés en texte clair ou au format obscur dans votre code. Je ne sais pas s'il existe une implémentation équivalente pour les autres plates-formes. Par conséquent, avec l'utilisation stricte de win32crypt, votre code n'est pas portable.
Je crois que le module peut être obtenu ici: http://timgolden.me.uk/pywin32-docs/win32crypt.html
Il existe plusieurs utilitaires ROT13 écrits en Python sur le Net - il suffit de les rechercher sur Google. ROT13 encoder la chaîne hors ligne, la copier dans la source, la décoder au moment de la transmission.
Mais c’est vraiment une faible protection ...
Connaissez-vous la fosse?
https://pypi.python.org/pypi/pit (py2 uniquement (version 0.3))
https://github.com/yoshiori/pit (cela fonctionnera sous py3 (version actuelle 0.4))
test.py
from pit import Pit
config = Pit.get('section-name', {'require': {
'username': 'DEFAULT STRING',
'password': 'DEFAULT STRING',
}})
print(config)
Courir:
$ python test.py
{'password': 'my-password', 'username': 'my-name'}
~/.pit/default.yml:
section-name:
password: my-password
username: my-name
Cela ne répond pas précisément à votre question, mais c'est lié. J'allais ajouter un commentaire, mais je n'étais pas autorisé… .. Je suis confronté au même problème et nous avons décidé d'exposer le script aux utilisateurs de Jenkins. Cela nous permet de stocker les informations d'identification de la base de données dans un fichier séparé, crypté et sécurisé sur un serveur, non accessible aux non-administrateurs. Cela nous permet également de créer une interface utilisateur et de limiter l’exécution.
Vous pouvez également envisager la possibilité de stocker le mot de passe en dehors du script et de le fournir au moment de l'exécution.
par exemple. fred.py
import os
username = 'fred'
password = os.environ.get('PASSWORD', '')
print(username, password)
qui peut être exécuté comme
$ PASSWORD=password123 python fred.py
fred password123
Des couches supplémentaires de "sécurité à travers l'obscurité" peuvent être obtenues en utilisant base64
(comme suggéré ci-dessus), en utilisant des noms moins évidents dans le code et en éloignant davantage le mot de passe réel du code.
Si le code est dans un référentiel, il est souvent utile de stocker les secrets en dehors de celui-ci , afin de pouvoir l'ajouter à ~/.bashrc
(ou à un coffre-fort, ou à un script de lancement, ... )
export SURNAME=cGFzc3dvcmQxMjM=
et remplacez fred.py
par
import os
import base64
name = 'fred'
surname = base64.b64decode(os.environ.get('SURNAME', '')).decode('utf-8')
print(name, surname)
puis vous reconnecter et
$ python fred.py
fred password123