Verschlüsselung mit C#

Tech-Essen

Mitglied
Hallo,
wie kann man in C# Passwörter sicher verschlüsseln und später wieder entschlüsseln?
Freue mich auf Antworten!
 
Und noch mal ich :p

Gar nicht.

Erste Info, da die Frage zeigt, keine Ahnung von Sicherheit zu haben: Einfach "Verschlüsselung" macht nichts sicherer, egal wie sicher die Verschlüsselung ist.

Erste vier Gegenfragen: Was wird mit dem Passwort geschützt? Gegen wen (Normale unbekannte Leute, Eltern, NSA, ...)? Was erwartest du dir vom Verschlüsseln? Und warum ist das Passwort irgendwo, wo es verschlüsselt werden kann, wo es also ohne Verschlüsselung auch gelesen werden kann?
 
Hi

Hier mal ein theoretischer(er) Ansatz:
wie kann man in C# Passwörter sicher verschlüsseln und später wieder entschlüsseln?
Wenn man etwas nicht entschlüsseln kann, dann war es nicht verschlüsselt. Man könnte eine Datei ja durch eine Reihe von Zufallszahlen gleicher Länge ersetzen, was den Inhalt "verdeckt", aber halt keinerlei Information mehr beinhaltet (etwas ähnliches wird mit XOR und One-Time-Pad gleicher Länge erreicht).
Ich möchte Dateien gegen "normale" Hacker schützen

In der Information Security muss man spezifizieren, was die "Threats" und was die "Threat agents" sind.
Sheel's
stimmt nur bedingt.
Zum Beispiel ist eine Verschlüsselung immer sicher, wenn man annimmt, dass der Gegner weder den Schlüssel rausfinden kann noch einfache Mathematik versteht.
Nimmt man den Dolev-Yao-Angreifer an, dann hat der Gegner vollen Zugriff auf das Netzwerk.
So wäre es zum Beispiel so, dass wenn du das Passwort ungeschützt über das Netzwerk sendest, dann keine Sicherheit besteht.

Nun scheinst du mit deiner Frage aber auf lokale Verschlüsselung, also ohne Netzwerkübertragung anzuspielen.
Hier lassen sich die folgenden Annahmen treffen:
a) Der Angreifer hat keinen Zugriff auf deinen Computer.
b) Der Angreifer hat eingeschränkten (=Keine Administratorrechte) auf deinen Computer.
c) Der Angreifer hat vollen Zugriff.

Zuerst die einfachen Fälle:
Im Fall a) ist Verschlüsselung nutzlos, da der Angreifer ohnehin nicht an die Datei kommen kann.
Im Fall c) ist die Verschlüsselung sinnlos, falls Passwörter und Dateien auf demselben Computer liegen.

Im Fall c) kommt es auf die Implementierung an: Liegen Passwörter in einem Administratorbereich, dann wären die Verschlüsselten Dateien "sicher"; der Angreifer kommt zwar an sie heran, kann sie aber nicht entschlüsseln.

In diesem Fall kommt es aber auch auf die Verschlüsselung an.
Es gibt symmetrische (Verschlüsselungschlüssel = Entschlüsselungsschlüssel) und asymmetrische (Verschlüsselungsschlüssel hat jeder, Entschlüsselungsschlüssel hat nur der, der es haben darf (private key)).

Asymmetrische Verschlüsselung ist teurer als symmetrische.
Heute als "sicher" gilt AES (Rjindael). Unsicher ist die Variation AES-ECB, aber AES-CBC ist der "de facto" Standard.

Und nun, um deine Frage zu beantworten:
https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx

Wichtig hier: Crypto ist konzeptuell sehr einfach, in der Implementierung sehr schwer.
Hier müsstest du der Implementierung von AES in C# vertrauen.
Default ist hier aber bereits CBC.

Um ein Passwort selbst zu setzen, musst du aber den Key selbst wählen und den IV (Initialization Vector) aufbewahren (Genau genommen muss der IV ein Teil des Passworts darstellen, d.h. mindestens den IV musst du im Klartext speichern).
Den IV kannst du dir (hoffentlich sicher, Vertrauensfrage) generieren lassen, den Key musst du selbst (wie auch immer) sicher machen.

Kryptographie ist schon schwer, das ganze dann korrekt zu nutzen (Information Security) ist noch viel schwerer.

Natürlich kannst du ruhig damit herumspielen, aber wenn du dann nicht ständig ein nagendes Gefühl der Unsicherheit hast, bist du entweder ein absolutes Genie oder du machst etwas falsch.

Aber wie gesagt: Viel Spass damit :)

Gruss
cwriter
 
Ist es sicher, wenn man das Passwort in eine .txt Datei schreibt und dann diese Datei mit dem Passwort verschlüsselt?
So kann das Programm nach der Eingabe des Passworts die Datei entschlüsseln und mit dem entschlüsselten Inhalt (das Passwort) das Passwort überprüfen
So könnte man das entschlüsseln:
C#:
key = Convert.FromBase64String("Passwort".PadLeft(32, 'x'));
byte[] iv = Convert.FromBase64String("RC0TQxaU5f8=");
TripleDES tdes = TripleDES.Create();
fs = new FileStream(Application.StartupPath + "\\users\\Username.txt", FileMode.Open);
CryptoStream cs = new CryptoStream(fs, tdes.CreateDecryptor(key, iv), CryptoStreamMode.Read);
pswd = new StreamReader(cs).ReadLine();
if(pswd == "Passwort")
{
             MessageBox.Show("Log-In erfolgreich!");
 }
cs.Close();
fs.Close();
 
Ist es sicher, wenn man das Passwort in eine .txt Datei schreibt und dann diese Datei mit dem Passwort verschlüsselt?
Vielleicht. Ob es sicherer ist? Sicher nicht.
Schlussendlich verschiebst du das Problem ja nur. Ob du jetzt das Passwort der Verschlüsselten Datei erraten musst oder das Passwort der Datei, in der der eigentliche Schlüssel liegt, ist vom Aufwand her nur ein konstanter Unterschied und daher für jeden Polynomiellen Angreifer gleich schwierig zu knacken.


Einige Anmerkungen zu deinem Beispielcode (ich hoffe schon, dass du den nicht so verwenden willlst):
1) FromBase64String: Ist ja nicht unbedingt ein Base64 string, wenn das Passwort Sonderzeichen beinhaltet? Mal davon abgesehen sollten Passwörter nur gehasht und gesalzen gespeichert (und verwendet) werden.
2) Dein Padding bringt aus Kryptographischer Sicht wenig bis gar nichts. Nimm PKCS#7 oder einen anderen erprobten Algorithmus dafür.
3) Der IV sollte immer neu gewählt werden (genau genommen sollte er sogar immer nur einmal vorkommen), also mit kryptographischem RNG erstellen und nicht einfach so festsetzen.
4) 3DES gilt noch als sicher, aber gibt es einen Grund, warum du nicht AES verwenden willst?
5) Nein, so kann man das nicht entschlüsseln. Der Witz der Verschlüsselung ist ja gerade, dass du nicht wissen kannst, ob ein Passwort stimmt (denn sonst würdest du Informationen preisgeben). Lass die Überprüfung auf ein Passwort weg und nutze den entschlüsselten Bytestring einfach weiter. Spätestens, wenn die Datei dann entschlüsselt wird, siehst du damit, ob das Passwort richtig war.
Falls du tatsächlich aus Bequemlichkeitsgründen eine Passwortüberprüfung haben willst: Speichere einen Hash und den benutzten Salt des Passworts (normalerweise wird der Hash selbst noch ein Dutzend mal neu gehasht) in der Datei im Klartext. Wenn der Nutzer ein Passwort eingibt, dann hashe diese Eingabe mit demselben Salt und demselben Algorithmus und überprüfe so, ob das Passwort dasselbe ist. So kannst du sicher sein, dass das richtige Passwort eingegeben wurde.
Aber das geht auch ohne den Umweg über eine weitere Datei...

Über die Sicherheit: Wie gesagt ist es nicht sicherer, aber auch nicht unbedingt unsicherer. Dein momentaner Code jedenfalls sorgt für eine ziemlich schwache Verschlüsselung (auch wenn 90% der Angreifer damit schon nichts mehr anfangen können, sind es die 10%, um die du dir wirklich Sorgen machen solltest).

Gruss
cwriter
 
Zurück