Ich muss sicher einen Benutzernamen und ein Passwort in Python speichern, was sind meine Optionen?

Ich schreibe ein kleines Python-Skript, das regelmäßig Informationen aus einem Drittanbieter-Service mit einem Benutzernamen und Passwort-Combo zieht. Ich brauche nicht etwas zu schaffen, das 100% kugelsicher ist (ist 100% sogar vorhanden), aber ich möchte gern ein gutes Maß an Sicherheit einbeziehen. Zumindest würde es lange dauern, bis jemand es zu brechen hat.

Dieses Skript wird nicht über eine GUI und wird regelmäßig von cron , so dass die Eingabe eines Passwortes jedes Mal, wenn es ausgeführt wird, um Dinge zu entschlüsseln wird nicht wirklich funktionieren, und ich muss den Benutzernamen und das Passwort in einer verschlüsselten Datei speichern oder Verschlüsselt in einer SQLite-Datenbank, was wäre vorzuziehen, da ich SQLite sowieso verwenden werde, und ich müsste das Passwort irgendwann bearbeiten. Darüber hinaus werde ich wahrscheinlich das ganze Programm in einer EXE verpacken, da es exklusiv für Windows an dieser Stelle ist.

Wie kann ich den Benutzernamen und das Passwort-Combo sicher speichern, um periodisch über einen cron Job benutzt zu werden?

7 Solutions collect form web for “Ich muss sicher einen Benutzernamen und ein Passwort in Python speichern, was sind meine Optionen?”

Ich empfehle eine ähnliche Strategie wie ssh-agent . Wenn du ssh-agent nicht direkt benutzen kannst, kannst du so etwas implementieren, damit dein Passwort nur im RAM bleibt. Der Cron-Job könnte Anmeldeinformationen konfiguriert haben, um das aktuelle Passwort von dem Agenten jedes Mal, wenn es ausgeführt wird, verwenden Sie es einmal, und de-Referenz es sofort mit der del Anweisung.

Der Administrator muss immer noch das Passwort eingeben, um ssh-agent, zum boot-time oder was auch immer zu starten, aber das ist ein vernünftiger Kompromiss, der es vermeidet, ein einfaches Text-Passwort auf der Festplatte zu speichern.

Nachdem ich die Antworten auf diese und damit zusammenhängende Fragen gesehen habe, habe ich einen Code mit einigen der vorgeschlagenen Methoden zur Verschlüsselung und Verdeckung von geheimen Daten zusammengestellt. Dieser Code ist speziell für, wenn das Skript ohne Benutzerintervention laufen muss (wenn der Benutzer es manuell startet, ist es am besten, dass sie das Passwort eingegeben haben und es nur im Speicher behalten, wie die Antwort auf diese Frage vorschlägt). Diese Methode ist nicht super-sicher; Grundsätzlich kann das Skript auf die geheimen Infos zugreifen, so dass jeder, der über einen vollständigen Systemzugriff verfügt, über das Skript und seine zugehörigen Dateien verfügt und auf sie zugreifen kann. Was das tut, verwechselt die Daten von der zufälligen Inspektion und lässt die Datendateien selbst sicher, wenn sie einzeln oder zusammen ohne das Skript untersucht werden.

Meine Motivation für dieses ist ein Projekt, das einige meiner Bankkonten abfragt, um Transaktionen zu überwachen – ich brauche es, um im Hintergrund zu laufen, ohne dass ich die Passwörter jede Minute oder zwei neu eingegeben habe.

Fügen Sie einfach diesen Code an die Spitze Ihres Skripts, ändern Sie die saltSeed und dann verwenden store () retrieve () und erfordern () in Ihrem Code nach Bedarf:

 from getpass import getpass from pbkdf2 import PBKDF2 from Crypto.Cipher import AES import os import base64 import pickle ### Settings ### saltSeed = 'mkhgts465wef4fwtdd' # MAKE THIS YOUR OWN RANDOM STRING PASSPHRASE_FILE = './secret.p' SECRETSDB_FILE = './secrets' PASSPHRASE_SIZE = 64 # 512-bit passphrase KEY_SIZE = 32 # 256-bit key BLOCK_SIZE = 16 # 16-bit blocks IV_SIZE = 16 # 128-bits to initialise SALT_SIZE = 8 # 64-bits of salt ### System Functions ### def getSaltForKey(key): return PBKDF2(key, saltSeed).read(SALT_SIZE) # Salt is generated as the hash of the key with it's own salt acting like a seed value def encrypt(plaintext, salt): ''' Pad plaintext, then encrypt it with a new, randomly initialised cipher. Will not preserve trailing whitespace in plaintext!''' # Initialise Cipher Randomly initVector = os.urandom(IV_SIZE) # Prepare cipher key: key = PBKDF2(passphrase, salt).read(KEY_SIZE) cipher = AES.new(key, AES.MODE_CBC, initVector) # Create cipher return initVector + cipher.encrypt(plaintext + ' '*(BLOCK_SIZE - (len(plaintext) % BLOCK_SIZE))) # Pad and encrypt def decrypt(ciphertext, salt): ''' Reconstruct the cipher object and decrypt. Will not preserve trailing whitespace in the retrieved value!''' # Prepare cipher key: key = PBKDF2(passphrase, salt).read(KEY_SIZE) # Extract IV: initVector = ciphertext[:IV_SIZE] ciphertext = ciphertext[IV_SIZE:] cipher = AES.new(key, AES.MODE_CBC, initVector) # Reconstruct cipher (IV isn't needed for edecryption so is set to zeros) return cipher.decrypt(ciphertext).rstrip(' ') # Decrypt and depad ### User Functions ### def store(key, value): ''' Sore key-value pair safely and save to disk.''' global db db[key] = encrypt(value, getSaltForKey(key)) with open(SECRETSDB_FILE, 'w') as f: pickle.dump(db, f) def retrieve(key): ''' Fetch key-value pair.''' return decrypt(db[key], getSaltForKey(key)) def require(key): ''' Test if key is stored, if not, prompt the user for it while hiding their input from shoulder-surfers.''' if not key in db: store(key, getpass('Please enter a value for "%s":' % key)) ### Setup ### # Aquire passphrase: try: with open(PASSPHRASE_FILE) as f: passphrase = f.read() if len(passphrase) == 0: raise IOError except IOError: with open(PASSPHRASE_FILE, 'w') as f: passphrase = os.urandom(PASSPHRASE_SIZE) # Random passphrase f.write(base64.b64encode(passphrase)) try: os.remove(SECRETSDB_FILE) # If the passphrase has to be regenerated, then the old secrets file is irretrievable and should be removed except: pass else: passphrase = base64.b64decode(passphrase) # Decode if loaded from already extant file # Load or create secrets database: try: with open(SECRETSDB_FILE) as f: db = pickle.load(f) if db == {}: raise IOError except (IOError, EOFError): db = {} with open(SECRETSDB_FILE, 'w') as f: pickle.dump(db, f) ### Test (put your code here) ### require('id') require('password1') require('password2') print print 'Stored Data:' for key in db: print key, retrieve(key) # decode values on demand to avoid exposing the whole database in memory # DO STUFF 

Die Sicherheit dieser Methode wäre deutlich verbessert, wenn os Berechtigungen auf die geheimen Dateien gesetzt wurden, um nur das Skript selbst zu lesen, und wenn das Skript selbst kompiliert und als ausführbare Datei (nicht lesbar) markiert wurde. Eines davon könnte automatisiert werden, aber ich habe nicht gestört. Es würde wahrscheinlich die Einrichtung eines Benutzers für das Skript und das Ausführen des Skripts als diesen Benutzer (und Einstellung Besitz der Skript-Dateien an diesen Benutzer).

Ich würde irgendwelche Vorschläge, Kritik oder andere Punkte der Verwundbarkeit lieben, die jeder denken kann. Ich bin ziemlich neu, um Krypto-Code zu schreiben, also was ich getan habe, könnte fast sicher verbessert werden.

Ich bin derzeit die Erforschung dieses Themas und die folgenden scheint die beste Lösung für meine Bedürfnisse zu sein … vielleicht wird es für andere kommen, die über diese Frage kommen.

Python-Schlüsselring-Bibliothek integriert sich mit der CryptProtectData API unter Windows, die Daten mit den Anmeldeinformationen der Benutzer verschlüsselt.

Der Gebrauch ist sehr einfach:

 keyring.set_password("system", "username", "password") keyring.get_password("system", "username") 

Elemente werden mit den Benutzern verschlüsselt Windows-Anmeldeinformationen, so dass andere Anwendungen, die in Ihrem Benutzerkonto ausgeführt werden, auf das Kennwort zugreifen können.

Um diese Schwachstelle zu verdecken, könnte man das Passwort in irgendeiner Weise verschlüsseln / verschleiern, bevor man es auf dem Schlüsselbund speichert. Natürlich würde jeder, der dein Skript anvisiert hat, einfach in der Lage sein, die Quelle zu betrachten und herauszufinden, wie man das Passwort unverschlüsselt / unauffällig macht, aber du würdest zumindest eine Anwendung verhindern, die alle Passwörter im Gewölbe aufsaugt und dir auch das Gleichgewicht macht .

Ich denke, das Beste, was Sie tun können, ist, die Skriptdatei und das System zu schützen, auf dem es läuft.

Grundsätzlich folgendes tun:

  • Dateisystemberechtigungen verwenden (chmod 400)
  • Starkes Passwort für das Konto des Eigentümers auf dem System
  • Verringern Sie die Fähigkeit, das System zu beeinträchtigen (Firewall, deaktivieren Sie nicht benötigte Dienste usw.)
  • Entfernen Sie administrative / root / sudo Privilegien für diejenigen, die es nicht brauchen

Es gibt nicht viel Sinn, das Passwort zu verschlüsseln: Die Person, die du versuchst, es zu verbergen, hat das Python-Skript, das den Code entschlüsseln muss. Der schnellste Weg, um das Passwort zu bekommen, wird eine Druckerklärung zum Python-Skript hinzufügen, kurz bevor es das Passwort mit dem Drittanbieter-Service verwendet.

So speichern Sie das Passwort als String im Skript, und base64 codieren es so, dass nur das Lesen der Datei ist nicht genug, dann rufen Sie es einen Tag.

Betriebssysteme haben oft Unterstützung für die Sicherung von Daten für den Benutzer. Im Falle von Fenstern sieht es aus wie es ist http://msdn.microsoft.com/en-us/library/aa380261.aspx

Sie können Win32 Apis von Python mit http://vermeulen.ca/python-win32api.html anrufen

Soweit ich verstehe, wird das die Daten so speichern, dass es nur von dem Konto abgerufen werden kann, das zum Speichern verwendet wird. Wenn Sie die Daten bearbeiten möchten, können Sie dies tun, indem Sie Code schreiben, um den Wert zu extrahieren, zu ändern und zu speichern.

Ich habe Kryptographie verwendet, weil ich Schwierigkeiten hatte, andere häufig erwähnte Bibliotheken auf meinem System zu installieren (zu kompilieren). (Win7 x64, Python 3.5)

 from cryptography.fernet import Fernet key = Fernet.generate_key() cipher_suite = Fernet(key) cipher_text = cipher_suite.encrypt(b"password = scarybunny") plain_text = cipher_suite.decrypt(cipher_text) 

Mein Skript läuft in einem physisch sicheren System / Raum. Ich verschlüssige Anmeldeinformationen mit einem "Verschlüsselungs-Skript" zu einer Konfigurationsdatei. Und dann entschlüsseln, wenn ich sie benutzen muss. "Encrypter script" ist nicht auf dem realen system, nur verschlüsselte config datei ist. Jemand, der den Code analysiert, kann leicht die Verschlüsselung durch die Analyse des Codes brechen, aber man kann es immer noch in eine EXE kompilieren, wenn nötig.

  • Pythons sicherste Methode zum Speichern und Abrufen von Passwörtern aus einer Datenbank
  • Entschlüsseln Sie Chrome Linux BLOB verschlüsselte Cookies in Python
  • Alte Python Hashing von links nach rechts - warum ist es schlecht?
  • Entschlüsseln einer Datei in einen Stream und Lesen des Streams in Pandas (hdf oder stata)
  • Verschlüsseln und Entschlüsseln mit PyCrypto AES 256
  • Wie AES verschlüsseln / entschlüsseln Dateien mit Python / PyCrypto in einer OpenSSL-kompatiblen Weise?
  • Was ist die beste / am einfachsten zu verwenden Verschlüsselung Bibliothek in python
  • Emulieren von SSHs SOCKS Proxy Tunnel in Python
  • Python-Verschlüsselung - Unerwartete Variablenrückgabe
  • Python und PGP / Verschlüsselung
  • Sicher verschlüsseln Sie ganzzahlige (bis zu 2 ^ 48) in den kürzesten URL-sicheren String
  • Python ist die beste Programmiersprache der Welt.