Hi@all
wollte erstmal anmerken, das mir das Forum sehr gut gefällt. Echt Klasse!
Nun zu meinem Problem. Bin mal auf den Dreh gekommen so ne Art verschlüsselungsprogramm zu schreiben,d.h. ein benutzer meldet sich an, Name und Passwort werden in einer Datei verschlüsselt. bei der nächsten Anmeldung wird erkannt das der benutzer schon angelegt ist und es wird anch dem Passwort gefragt, wenn das Passwort stimmt gehts auch weiter. Allerdings kommt ein "Stack Overflow" wenn das Passwort nicht stimmt. Ist mir auch alles verständlich, nur suche ich eine Form, wie ich diesen fehler abfangen kann um dem benutzer quasi mitzuteilen das das Passwort falsch ist und vorallem das Programm nicht mit dem fehler beendet wird!?
Vielleicht könntet ihr mir mal einen guten Ansatz aufzeigen!
Danke,Phil
public static void Decrypt(string fileIn,
string fileOut, string Password)
{
FileStream fsIn = new FileStream(fileIn, //Ausgabe und Eingabe vertauschen
FileMode.Open, FileAccess.Read, FileShare.None);
FileStream fsOut = new FileStream(fileOut,
FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); //FileShare sperrt den Vorgang für andere Zugriffe
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
CryptoStream cs = new CryptoStream(fsOut,
alg.CreateDecryptor(), CryptoStreamMode.Write);
int bufferLen = 4096;
byte[] buffer = new byte[bufferLen];
int bytesRead;
do
{
bytesRead = fsIn.Read(buffer, 0, bufferLen);
cs.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
cs.Close(); ----> STACK OVERFLOW
fsIn.Close();
}
Hallo Philzstift,
cs.Close(); ----> STACK OVERFLOW
hm, ich kann mir nicht recht vorstellen, dass der StackOverflow durch das Close ausgelöst wird.
... wie ich diesen fehler abfangen kann ...
Ein StackOverflow kommt i.d.R durch ein Programmierfehler. Also sollte man den StackOverflow nicht abfangen, sondern durch Fehlerkorrektur vermeiden.
... um dem benutzer quasi mitzuteilen das das Passwort falsch ist.
Diese Fall sollte eigentlich einfacher sein, als der, wenn das Passwort stimmt.
herbivore
Aus meiner Erfahrung kommt ien Stack Overflow zustanden wenn eine schleife unendlich läuft.
Daher die do..while schleife, ist die korrekt?
Ich bin ehrlich gesagt noch nicht ganz erfahren im Code aber so gesehen könnte der StackOverflow zustande kommen. Denn du prüfsst das verarbeitete byte ob es nicht null ist und nicht das nächste.
Hi,
eine unentliche Schleife muss keine Stack-Overflow-Exception auslösen. Wie der Name des Fehlers bereits sagt, wird er ausgelöst, wenn der Stack überläuft. Dies geschieht oft und gerne bei Rekursionen, jedoch sehe ich in der Schleife keinen Grund für einen Overflow. Es wird ja nichts auf den Stack geschoben.
MfG,
Grouser.
@Grouser
entschuldige, "kann unteranderem vorkommen" währen die richtigen Worte gewesen.
Original von Speeedy
entschuldige, "kann unteranderem vorkommen" währen die richtigen Worte gewesen.
Nichtmal das. Der Stack wird nur in zwei Szenarien genutzt: Initialisierung eines lokalen Wertetypen (z.B. int) oder bei der Übergabe von Parametern auf dem Stack. Schleifen an sich können also nicht der Verursacher von Stackoverflows sein. Ersteres scheidet praktisch aus (wer definiert schon tausende von Variablen...). Bleibt also praktisch immer eine Rekursion als Ursache.
Ich würde mal den fin-Stream vor dem CryptoStream schließen und auch den Out-Stream zumachen.
Guten Abend,
danke erstmal für die vielen Tips.
Habe erst das fsin.Close(); über den Cryptostream gesetzt, damit kamen allerdings neue Probleme. Man konnte somit nicht mehr auf die dadurch geschlossene Datei zugreifen. also "fsin.Close();" wieder ans Ende , dann noch das "fsOut.Close();" dazu und dann das cs.Close(); ausgeklammert und siehe da es läuft ohne Stack Overflow....habe alle Varianten durchprobiert, es schien doch an dem cs.Close(); gelegen zu haben!
public static void Decrypt(string fileIn,
string fileOut, string Password)
{
FileStream fsIn = new FileStream(fileIn, //Ausgabe und Eingabe vertauschen
FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
FileStream fsOut = new FileStream(fileOut,
FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); //FileShare sperrt den Vorgang für andere Zugriffe
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
CryptoStream cs = new CryptoStream(fsOut,
alg.CreateDecryptor(), CryptoStreamMode.Write);
int bufferLen = 4096;
byte[] buffer = new byte[bufferLen];
int bytesRead;
do
{
bytesRead = fsIn.Read(buffer, 0, bufferLen);
cs.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
[B]fsIn.Close();
fsOut.Close();[/B]
}
Lg,Phil
Hallo Philzstift,
dass du cs.Close() weglässt kann aber nicht die Lösung sein 🤔
Ich bin der Meinung, du hast den Algorithmus nicht vollständig Configuriert bzw. beachtest dessen Verhalten nicht ausreichend ...
Ich lass mich auch gern eines besseren belehren.
Bei mir kommt beim Close jedenfalls ne CryptographicException. Diese wird verursacht durch den übergebenen, zu verschlüsselnden Block deren Länge nicht mit der Blockgröße des Algorithmus übereinstimmt (Standard == 128 ). Außerdem füllst du den Block nicht mit den entsprechenden Füllzeichen (Standard == PCKS7) auf, wodurch der Algorithmus nicht richtig arbeiten kann.
Außerdem würd ich dir für Stream using ans Herz legen, dann vergisst du auch kein Close, Dispose oder Flush mehr 😉
Bei mir läuft folgendes ohne Probleme durch:
public static void Decrypt(string fileIn, string fileOut, string Password)
{
using (FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
alg.Padding = PaddingMode.Zeros; // Standard ist PKCS7
using (CryptoStream cs = new CryptoStream(fsOut, alg.CreateDecryptor(), CryptoStreamMode.Write))
{
byte[] buffer = new byte[alg.BlockSize];
int bytesRead = 0;
do
{
bytesRead = fsIn.Read(buffer, 0, buffer.Length);
//
// Block mit 0 füllen
//
if (bytesRead < buffer.Length)
{
for (int i = bytesRead; i < buffer.Length; i++)
buffer[i] = 0;
}
if (bytesRead > 0)
cs.Write(buffer, 0, buffer.Length);
} while (bytesRead > 0);
}
}
}
}
Grüße él toro.
So einfach wie möglich, aber nicht einfacher. [Albert Einstein]
take a look at
* baer-torsten.de
* codinghints