Laden...

Verschlüsselung von Strings

Letzter Beitrag vor 17 Jahren 11 Posts 15.838 Views
Verschlüsselung von Strings

Moin zusammen!

Ich habe ein Problem mit der Verschlüsselung und Entschlüsselung von Strings.
Im Forum habe ich dazu keine Lösung gefunden.
Muss das ganze in VB.NET machen... Meine Klasse nimmt einen String entgegen, verschlüsselt ihn und gibt den String zurück, gleicher Ablauf beim Entschlüsseln.
Für das Ver- und Entschlüsseln wird z.Z. noch das gleiche Rijndael-Objekt genutzt, sollte ja zum testen erstmal reichen.
1.Problem:
Beim Entschlüsseln kommt der Original-String nicht heraus.
2.Problem:
Wenn ich cStream.Flush durch cStream.FlushFinalData ersetze, kommt eine CryptographicException beim Entschlüsseln mit der Meldung "Zeichenabstände sind ungültig und können nicht entfernt werden".

Würde es auch lieber mit StreamWriter und StreamReader machen, aber damit bekomme ich garkeine Daten in den Stream...

Hoffe mir kann jemand helfen, dafür danke ich euch schonmal im voraus!!!


Imports System.IO
Imports System.Security.Cryptography

Public Class Cryptography
    Private rijnd As SymmetricAlgorithm

    Public Sub New()
        rijnd = Rijndael.Create()
    End Sub

    Public Function Encrypt(ByVal strData As String) As String
        Try
            Dim memStream As New MemoryStream()
            Dim transform As ICryptoTransform = rijnd.CreateEncryptor()
            Dim cStream As New CryptoStream(memStream, transform, CryptoStreamMode.Write)

            Dim byteData() As Byte = System.Text.Encoding.UTF8.GetBytes(strData)
            cStream.Write(byteData, 0, byteData.Length)
            cStream.Flush()

            Dim str As String = Convert.ToBase64String(memStream.ToArray())
            Return str
        Catch ex As Exception
            Console.WriteLine(ex.ToString())
            Return ""
        End Try
    End Function

    Public Function Decrypt(ByRef strData As String) As String
        Try
            Dim memStream As New MemoryStream()
            Dim transform As ICryptoTransform = rijnd.CreateDecryptor()
            Dim cStream As New CryptoStream(memStream, transform, CryptoStreamMode.Write)

            Dim byteData() As Byte = System.Text.Encoding.UTF8.GetBytes(strData)
            cStream.Write(byteData, 0, byteData.Length)
            cStream.Flush()

            Dim str As String = Convert.ToBase64String(memStream.ToArray())
            Return str
        Catch ex As Exception
            Console.WriteLine(ex.ToString())
            Return ""
        End Try
    End Function
End Class

Muss das ganze in VB.NET machen...

will ja nicht meckern... aber das ist eine C# Forum 🙂

Wär mir auch lieber wenn ich das in C# machen könnte, aber VB.NET ist Vorgabe der Firma... Und da ich hier für C# immer gute Lösungen gefunden hab, hoffe ich, ich darf euch einmal mit VB nerven!

Hab jetzt dieses Beispiel aus der MSDN:


using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

class RijndaelSample
{

    static void Main()
    {
        try
        {
            // Create a new Rijndael object to generate a key
            // and initialization vector (IV).
            Rijndael RijndaelAlg = Rijndael.Create();

            // Create a string to encrypt.
            string sData = "Here is some data to encrypt.";
            string FileName = "CText.txt";

            // Encrypt text to a file using the file name, key, and IV.
            EncryptTextToFile(sData, FileName, RijndaelAlg.Key, RijndaelAlg.IV);

            // Decrypt the text from a file using the file name, key, and IV.
            string Final = DecryptTextFromFile(FileName, RijndaelAlg.Key, RijndaelAlg.IV);

            // Display the decrypted string to the console.
            Console.WriteLine(Final);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

        Console.ReadLine();
    }

    public static void EncryptTextToFile(String Data, String FileName, byte[] Key, byte[] IV)
    {
        try
        {
            // Create or open the specified file.
            FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);

            // Create a new Rijndael object.
            Rijndael RijndaelAlg = Rijndael.Create();

            // Create a CryptoStream using the FileStream 
            // and the passed key and initialization vector (IV).
            CryptoStream cStream = new CryptoStream(fStream,
                RijndaelAlg.CreateEncryptor(Key, IV),
                CryptoStreamMode.Write);

            // Create a StreamWriter using the CryptoStream.
            StreamWriter sWriter = new StreamWriter(cStream);

            try
            {
                // Write the data to the stream 
                // to encrypt it.
                sWriter.WriteLine(Data);
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: {0}", e.Message);
            }
            finally
            {
                // Close the streams and
                // close the file.
                sWriter.Close();
                cStream.Close();
                fStream.Close();
            }
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
        }
        catch (UnauthorizedAccessException e)
        {
            Console.WriteLine("A file error occurred: {0}", e.Message);
        }

    }

    public static string DecryptTextFromFile(String FileName, byte[] Key, byte[] IV)
    {
        try
        {
            // Create or open the specified file. 
            FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);

            // Create a new Rijndael object.
            Rijndael RijndaelAlg = Rijndael.Create();

            // Create a CryptoStream using the FileStream 
            // and the passed key and initialization vector (IV).
            CryptoStream cStream = new CryptoStream(fStream,
                RijndaelAlg.CreateDecryptor(Key, IV),
                CryptoStreamMode.Read);

            // Create a StreamReader using the CryptoStream.
            StreamReader sReader = new StreamReader(cStream);

            string val = null;

            try
            {
                // Read the data from the stream 
                // to decrypt it.
                val = sReader.ReadLine();


            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: {0}", e.Message);
            }
            finally
            {

                // Close the streams and
                // close the file.
                sReader.Close();
                cStream.Close();
                fStream.Close();
            }

            // Return the string. 
            return val;
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
            return null;
        }
        catch (UnauthorizedAccessException e)
        {
            Console.WriteLine("A file error occurred: {0}", e.Message);
            return null;
        }
    }
}


Jetzt möchte ich, dass nicht ein FileStream, sondern ein MemoryStream verwendet wird.
Statt den Filenames lasse ich den String zum Ver-/Entschlüsseln übergeben, aus dem FileStream habe ich ein MemoryStream gemacht.
Beim Entschlüsseln schreibe ich da die zu entschlüsselnden Bytes aus dem übergebenen String rein. Dann gehts so weiter wie im MSDN-Beispiel.
Jetzt kommt die Fehlermeldung bei val = sReader.ReadLine();
"Die Länge der zu entschlüsselnden Daten ist ungültig."

Hat das evtl. mit dem Encoding zu tun??
Benutze System.Text.Encoding.UTF8.GetBytes!
Das Problem scheint ja nur aufzutauchen, wenn zwischendurch in Strings umgewandelt wird. Das Schreiben und Lesen aus Dateien funktioniert ja einwandfrei!

Langsam verzweifle ich an der Kryptographie...

Original von nin

Muss das ganze in VB.NET machen...

will ja nicht meckern... aber das ist eine C# Forum 🙂

Das Forum ist für C# und .NET, und VB.NET ist sehr wohl .NET, der Unterschied zu C# ist ja kurz gesagt ja nur ein bisschen Grammatik...

würde es in etwa so machen (MSDN bisschen abgeändert)

using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

class RijndaelSample
{

    
    public static string EncryptText(String Data, byte[] Key, byte[] IV)
    {
        try
        {
            // Create or open the specified file.
            MemoryStream ms = new MemoryStream();

            // Create a new Rijndael object.
            Rijndael RijndaelAlg = Rijndael.Create();

            // Create a CryptoStream using the FileStream
            // and the passed key and initialization vector (IV).
            CryptoStream cStream = new CryptoStream(ms,
                RijndaelAlg.CreateEncryptor(Key, IV),
                CryptoStreamMode.Write);

            // Create a StreamWriter using the CryptoStream.
            StreamWriter sWriter = new StreamWriter(cStream);

            try
            {
                // Write the data to the stream
                // to encrypt it.
                sWriter.WriteLine(Data);
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: {0}", e.Message);
            }
            finally
            {
                // Read MemoryStreamContent
                Byte[] b = ms.ToArray();
                // Close the streams and
                // close the file.
                sWriter.Dispose();
                cStream.Dispose();
                ms.Dispose();
                return Encoding.UTF8.GetString(b);
            }
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
        }
        catch (UnauthorizedAccessException e)
        {
            Console.WriteLine("A file error occurred: {0}", e.Message);
        }
       return null;
    }

    public static string DecryptText(String Crypted, byte[] Key, byte[] IV)
    {
        try
        {
            // Create MemoryStream
            Byte[] b=Encoding.UTF8.GetBytes(Crypted);
            MemoryStream ms = New MemoryStream(b);

            // Create a new Rijndael object.
            Rijndael RijndaelAlg = Rijndael.Create();

            // Create a CryptoStream using the FileStream
            // and the passed key and initialization vector (IV).
            CryptoStream cStream = new CryptoStream(fStream,
                RijndaelAlg.CreateDecryptor(Key, IV),
                CryptoStreamMode.Read);

            // Create a StreamReader using the CryptoStream.
            StreamReader sReader = new StreamReader(cStream);

            string val = null;

            try
            {
                // Read the data from the stream
                // to decrypt it.
                val = sReader.ReadLine();


            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: {0}", e.Message);
            }
            finally
            {

                // Close the streams and
                // close the file.
                sReader.Dispose();
                cStream.Dispose();
                ms.Dispose();
            }

            // Return the string.
            return val;
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
            return null;
        }
        catch (UnauthorizedAccessException e)
        {
            Console.WriteLine("A file error occurred: {0}", e.Message);
            return null;
        }
    }
}

Hallo zusammen,

hier ein mehr oder weniger offizielles Statement:

Das Forum ist für C# und .NET

Eben, es kommt nur darauf an, wie man das UND interpretiert. 🙂 Es steht ja UND da und nicht ODER. 😉 Und wenn man sich anschaut, wie wenige Fragen hier im Forum zu VB (also ich meine VB.NET) gestellt werden, ist der allgemeine Konsens, dass dies in erster Linie ein C#- und eben kein VB-Forum ist. Und wer eine Frage zu VB hat oder langen VB Code postet, muss damit rechnen, eine entsprechende Reaktion zu bekommen.

Andererseits sind Fragen zu VB nicht grundsätzlich ausgeschlossen. Die Überlegung von CF123 vollkommen legitim:

Wär mir auch lieber wenn ich das in C# machen könnte, aber VB.NET ist Vorgabe der Firma... Und da ich hier für C# immer gute Lösungen gefunden hab, hoffe ich, ich darf euch einmal mit VB nerven!

Ich denke der einfachste Weg, Problemen wegen VB-Fragen aus dem Weg zu gehen oder zumindest einer eventuellen "Anmache" locker begegnen zu können, ist die Fragen in "Rund um die Programmierung zu stellen:

Rund um die Programmierung
Design, Entwurfsmuster, Algorithmen, andere Sprachen, andere Bibliotheken, Ansteuerung von Geräten, Hardware-Schnittstellen, Reporting, Sicherheit, ...

der Unterschied zu C# ist ja kurz gesagt ja nur ein bisschen Grammatik

Das ist sicher richtig und wenn die Frage sich rein auf die Benutzung der Frameworkklassen und nicht auf spezielle VB-Syntaxfragen bezieht, ist die Sprache im Prinzip nebensächlich, nur fühlen sich viele C# Programmierer von der VB-Syntax schlicht abgestoßen. 🙂

Um es nochmal auf den Punkt zu bringen: In "Rund um die Programmierung" sind Fragen zu VB zulässig. Deshalb habe ich diesen Thread auch dorthin verschoben.

herbivore

Erstmal vielen Dank für deine Bemühungen!!!

Ich denke, dass Problem hat nichts mit VB zu tun, deswegen hab ich es jetzt ja auch in C# gepostet!

Habs jetzt wie onlinegurke gemacht.
Problem immer noch: "Die Länge der zu entschlüsselnden Daten ist ungültig."
(CryptographicEcception) in Zeile val = sReader.ReadLine

Noch irgendwelche Ideen??

Hallo CF123,

such mal hier nach der Fehlermeldung - die gab es schon ein paar mal - und poste bitte einen Verweis auf die Lösung, wenn du was findest.

herbivore

Mit einem Artikel aus der MSDN hab ich es nun hinbekommen:
MSDN - Kryptographie leicht gemacht

Dort wird es so gemacht:


private string EncryptString(string Value) 
{ 
  ICryptoTransform ct; 
  MemoryStream ms; 
  CryptoStream cs; 
  byte[] byt; 
  ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV); 
  byt = Encoding.UTF8.GetBytes(Value); 
  ms = new MemoryStream(); 
  cs = new CryptoStream(ms, ct, CryptoStreamMode.Write); 
  cs.Write(byt, 0, byt.Length); 
  cs.FlushFinalBlock(); 
  cs.Close(); 
  return Convert.ToBase64String(ms.ToArray()); 
}


private string DecryptString(string Value) 
{ 
   ICryptoTransform ct; 
   MemoryStream ms; 
   CryptoStream cs; 
   byte[] byt; 
   ct = mCSP.CreateDecryptor(mCSP.Key, mCSP.IV); 
   byt = Convert.FromBase64String(Value); 
   ms = new MemoryStream(); 
   cs = new CryptoStream(ms, ct, CryptoStreamMode.Write); 
   cs.Write(byt, 0, byt.Length); 
   cs.FlushFinalBlock(); 
   cs.Close(); 
   return Encoding.UTF8.GetString(ms.ToArray()); 
}

Fehler in meinem zuerst geposteten Code (VB.NET):
Verschlüsselung:
String zu Byte-Array über UTF8-Encoding
Byte-Array zu String über ToBase64String
Entschlüsselung:
String zu Byte-Array über UTF8-Encoding
Byte-Array zu String über ToBase64String

Richtig ist natürlich:
Verschlüsselung:
String zu Byte-Array über UTF8-Encoding
Byte-Array zu String über ToBase64String
Entschlüsselung:
String zu Byte-Array über FromBase64String
Byte-Array zu String über UTF8-Encoding

Also war das Problem wirklich wie vermutet das Encoding!

Danke nochmal für alle Hilfeversuche!!!