Ich arbeite an einer Python / Django-App, die unter anderem Daten mit einer Vielzahl anderer Dienste synchronisiert, einschließlich Samba-Shares, SSH-Servern, Google-Apps und anderen. Daher müssen die Anmeldeinformationen für den Zugriff auf diese Dienste gespeichert werden. Es wäre wohl eine schlechte Idee, sie als unverschlüsselte Felder zu speichern, da ein SQL-Injection-Angriff die Anmeldeinformationen abrufen könnte. Also müsste ich die Credits vor dem Speichern verschlüsseln - gibt es dafür zuverlässige Bibliotheken?
Sobald die Werte verschlüsselt sind, müssen sie entschlüsselt werden, bevor sie verwendet werden können. Es gibt zwei Anwendungsfälle für meine App:
Oder gibt es einen anderen Ansatz für dieses Problem, das ich ergreifen sollte?
Das erste Speichern auf einem Server, das ausreicht, um sich bei einer Vielzahl von Systemen anzumelden, sieht wie ein Albtraum aus. Ein kompromittierender Code auf Ihrem Server wird alle, unabhängig von der Verschlüsselung, verlieren.
Sie sollten nur die Anmeldeinformationen speichern, die zur Ausführung Ihrer Aufgabe erforderlich sind (z. B. Dateien synchronisieren). Für Server sollten Sie einen Synchronisationsserver wie RSync verwenden, für Google die Protokolle wie OAuth usw. Auf diese Weise werden, wenn Ihr Server kompromittiert ist, nur die Daten und nicht der Zugriff auf Systeme verloren gehen.
Als Nächstes werden diese Anmeldedaten verschlüsselt. Für die Kryptographie empfehle ich Ihnen PYCrypto .
Für alle Zufallszahlen, die Sie in Ihrer Kryptographie verwenden würden, generieren Sie diese mit Crypto.Random (oder einer anderen starken Methode), um sicher zu gehen, dass sie stark genug sind.
Sie sollten verschiedene Anmeldeinformationen nicht mit demselben Schlüssel verschlüsseln. Die Methode, die ich empfehlen würde, ist dies:
Wenn Sie entschlüsseln müssen, nehmen Sie einfach S , erstellen Sie das K und entschlüsseln Sie es mit derselben IV.
Für Hash würde ich SHA1 empfehlen, für die Verschlüsselung - AES. Hashes und symmetrische Cypher sind schnell genug, also würde es für größere Schlüsselgrößen nicht schaden.
Dieses Schema ist an einigen Stellen etwas überholt, aber auch das würde nicht schaden.
Aber denken Sie noch einmal daran, die beste Methode zum Speichern von Anmeldeinformationen besteht nicht darin, Anmeldeinformationen zu speichern, und wenn nötig, sollten Sie die am wenigsten privilegierten verwenden, mit denen Sie die Aufgabe ausführen können.
Ich habe das gleiche Problem und habe das in den letzten Tagen erforscht. Die Lösung von @Rostislav ist ziemlich gut, aber sie ist unvollständig und etwas veraltet.
Zuerst gibt es eine neue Bibliothek für die Kryptographie, die entsprechend Kryptografie genannt wird. Es gibt eine gute Anzahl von Gründen, diese Bibliothek anstelle von PyCrypto zu verwenden, aber die wichtigsten, die mich angezogen haben, sind:
Sie können mehr über die Gründe für das Erstellen der neuen Bibliothek auf LWN lesen.
Zweitens empfiehlt die andere Antwort die Verwendung von SHA1 als Verschlüsselungsschlüssel. SHA1 ist gefährlich schwach und wird schwächer . Der Ersatz für SHA1 ist SHA2, und außerdem solltest du deinen Hash wirklich salzen und ihn entweder mit bcrypt erweitern oder PBKDF2 . Salzen ist wichtig als Schutz gegen Regenbogen-Tische und Stretching ist ein wichtiger Schutz gegen Brute-Forcing.
(Bcrypt ist weniger getestet, aber dafür entwickelt, viel Speicher zu verwenden, und PBKDF2 ist langsam und wird von NIST empfohlen. In meiner Implementierung verwende ich PBKDF2. Wenn Sie mehr über die Unterschiede wissen wollen, lesen Sie dies .)
Für die Verschlüsselung sollte AES im CBC-Modus mit einem 128-Bit-Schlüssel verwendet werden, wie oben erwähnt - der sich nicht geändert hat, obwohl er jetzt in eine Spezifikation aufgerollt ist . Der Initialisierungsvektor wird automatisch in dieser Bibliothek für Sie generiert, so dass Sie das sicher vergessen können.
Die anderen Antworten stimmen ziemlich gut damit überein, dass Sie die Handhabung der Schlüssel sorgfältig in Betracht ziehen und sich für etwas wie OAuth entscheiden sollten, wenn Sie können. Aber angenommen, das ist nicht möglich (es ist nicht in meiner Implementierung), haben Sie zwei Anwendungsfälle: Cron Jobs und Interactive.
Der Anwendungsfall Cron-Job läuft darauf hinaus, dass Sie einen Schlüssel an einem sicheren Ort aufbewahren und ihn zum Ausführen von Cron-Jobs verwenden müssen. Ich habe das nicht studiert, deshalb werde ich hier nicht antworten. Ich denke, es gibt viele gute Möglichkeiten, dies zu tun, aber ich kenne den einfachsten Weg nicht.
Für den Anwendungsfall Interaktiv müssen Sie ein Benutzerkennwort erfassen, daraus einen Schlüssel generieren und diesen Schlüssel anschließend zum Entschlüsseln der gespeicherten Anmeldeinformationen verwenden.
So würde ich all das oben mit der Cryptography-Bibliothek tun:
%Vor%Entschlüsselung sieht dann wie folgt aus:
%Vor%Nehmen wir an, Ihre DB ist ins Internet gelangt. Was kann ein Angreifer tun? Nun, der Schlüssel, den wir für die Verschlüsselung verwendet haben, hat den 100.000sten SHA256-Hash des gesalzenen Passworts Ihres Benutzers genommen. Wir haben das Salz und unsere Verschlüsselung in Ihrer Datenbank gespeichert. Ein Angreifer muss daher entweder:
Ich denke, das ist ziemlich solide.
Es gibt jedoch noch eine andere Sache, über die man nachdenken sollte. PBKDF2 wurde entwickelt, um langsam zu sein. Es erfordert viel CPU-Zeit. Das bedeutet, dass Sie sich DDOS-Angriffen öffnen, wenn Benutzer PBKDF2-Hashes generieren können. Sei darauf vorbereitet.
All dies gesagt, ich denke, es gibt Bibliotheken, die einiges für Sie tun werden. Google rund um Dinge wie django verschlüsseltes Feld . Ich kann über diese Implementierungen keine Versprechungen machen, aber vielleicht wirst du etwas darüber lernen, wie andere das gemacht haben.
Vielleicht können Sie sich auf ein Mehrbenutzerschema verlassen, indem Sie Folgendes erstellen:
django
), der nicht berechtigt ist, auf die Anmeldeinformationen zuzugreifen sync
). Beide können sich in der Gruppe django
befinden, damit sie auf die App zugreifen können. Danach erstellen Sie ein Skript (ein Django-Befehl, z. B. manage.py sync-external
), der die gewünschten Einstellungen synchronisiert.
Auf diese Weise hat der django
-Benutzer Zugriff auf die App und das Synchronisierungsskript, aber nicht die Anmeldeinformationen, da nur der sync
-Benutzer dies tut. Wenn jemand versucht, das Skript ohne die Anmeldeinformationen auszuführen, wird dies natürlich zu einem Fehler führen.
Das Linux-Berechtigungsmodell ist meiner Meinung nach eine "gute Idee", aber ich bin kein Sicherheitsexperte, also denken Sie daran. Wenn jemand etwas darüber zu sagen hat, was oben ist, zögere nicht!
Tags und Links python django security encryption credentials