© Martin Korneffel, Stuttgart 2006 +++ email: Martin.Korneffel@t-online.de +++ web: www.s-line.de/homepages/trac
Vertraulichkeit: Beschränken des Zugriffs auf Informationen auf einen definierten Benutzerkreis
Sicherstellen der Datenintegrität: Schützen von sensitiven Daten vor unberechtigten Änderungen
Authentizität: Nachweise über den Verfasser von Informationen.
Geringer Rechenaufwand bei der Ver- und Entschlüsselung
Sicher für Schlüssellängen >= 1024 bit
Sender muß über zusätzlichen geheimen Kanal den Schlüssel an den Empfänger senden
RijndaelManaged ist die einzige Klasse der sym. Verschlüsselungsverfahren, die vollständig in Managed Code implementiert ist. Ihre Verwendung wird empfohlen.
Die Basisklasse aller symetrischen Kryptografieverfahren ist SysmetricAlgorithm
Die
Ver- und Entschlüsselung erfolgt durch Objekte, deren Klasse die
Schnittstelle ICryptoTransform implementieren.
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Security.Cryptography; namespace u2_SymetricAlgorithm { class Program { const string password = "wa17er"; const string txtSalt = "Das Salz in der Suppe"; // Aus einem Passwort wird ein Schlüssel generiert static byte[] MakeKey(string password, int KeySizeInBits) { // Einen Schlüssel aus einem Passwort generieren byte[] salt = Encoding.ASCII.GetBytes(txtSalt); Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt); // Schlüssel und initialisierungsvektor aus dem Passwort generieren // Die Schlüsselgrößen werden in Bit angegeben, weshalb durch 8 // geteilt werden muß return key.GetBytes(KeySizeInBits / 8); } // Datei "inputPath" wird mit einem aus "password" generierten Schlüssel // verschlüsselt. Verschlüsselte Daten werden in "outputPath" geschrieben static void encrypt(string inputPath, string password, string outputPath) { // Ein Objekt einer Klasse für die sym. Verschlüsselung erstellen RijndaelManaged symAlgo = new RijndaelManaged(); // Schlüssel aus Passwort generieren symAlgo.Key = MakeKey(password, symAlgo.KeySize); // Initialisierungsvektor aus Passwort bilden symAlgo.IV = MakeKey(password, symAlgo.BlockSize); // Datei mit Geheimtext einlesen in Bytearray FileStream infstream = new FileStream(inputPath, FileMode.Open); byte[] txt = new byte[infstream.Length]; infstream.Read(txt, 0, (int)infstream.Length); infstream.Close(); // Ausgabedatei für verschlüsselten Text öffnen FileStream outfstream = new FileStream(outputPath, FileMode.OpenOrCreate); ICryptoTransform trafo = symAlgo.CreateEncryptor(); CryptoStream encryptStream = new CryptoStream(outfstream, trafo, CryptoStreamMode.Write); // In verschlüsselte Datei Schreiben encryptStream.Write(txt, 0, txt.Length); // Datenströme schliessen encryptStream.Close(); outfstream.Close(); } // Verschlüsselte Daten aus der Datei "pathEncrypted" wird mit aus "password" // generierten Schlüssel entschlüsselt static string decrypt(string pathEncrypted, string password) { // Ein Objekt einer Klasse für die sym. Verschlüsselung erstellen RijndaelManaged symAlgo = new RijndaelManaged(); // Schlüssel aus Passwort generieren symAlgo.Key = MakeKey(password, symAlgo.KeySize); // Initialisierungsvektor aus Passwort bilden symAlgo.IV = MakeKey(password, symAlgo.BlockSize); FileStream infstream = new FileStream(pathEncrypted, FileMode.Open); ICryptoTransform trafo = symAlgo.CreateDecryptor(); // Entschlüsseln mittels CryptoStream CryptoStream decryptStream = new CryptoStream(infstream, trafo, CryptoStreamMode.Read); StreamReader reader = new StreamReader(decryptStream); string txt = reader.ReadToEnd(); reader.Close(); return txt; } const string pathGeheimtext = @"..\..\text.txt"; const string pathVerschluesselterText = @"..\..\text.enc"; static void Main(string[] args) { // Ausgabe des zu verschlüsselnden Textes StreamReader reader = new StreamReader(pathGeheimtext); string txt = reader.ReadToEnd(); reader.Close(); Console.WriteLine("Inhalt des Geheimtextes: "); Console.WriteLine(txt); encrypt(pathGeheimtext, password, pathVerschluesselterText); reader = new StreamReader(pathVerschluesselterText); txt = reader.ReadToEnd(); reader.Close(); Console.WriteLine("Inhalt des Verschlüsselten Textes: "); Console.WriteLine(txt); txt = decrypt(pathVerschluesselterText, password); Console.WriteLine("Inhalt des entschlüsselten Textes: "); Console.WriteLine(txt); } } }
Öffentlicher Schlüssel zum Verschlüsseln kann frei verteilt werden.
Mit private- Key verschlüsselte Nachrichten können nur mit zugehörigen öffentlichen Schlüsseln entschlüsselt werden (Digitale Signatur)-> weiter Anwendung zum Authentifizieren
sicher
Sehr rechenintensiv
using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptography; using System.IO; namespace u3_RSA_Keys { class Program { // Erzeugen eines neuen Schlüssel, oder Lesen eines zuvor generierten // aus dem CryptoServiceProvider static void RsaKeyAndCspParameter(string NameCspContainer) { // Zugriff auf den CryptoServiceProvider zum speichern und abrufen der Schlüssel CspParameters csp = new CspParameters(); csp.KeyContainerName = NameCspContainer; RSACryptoServiceProvider myRsa = new RSACryptoServiceProvider(csp); myRsa.PersistKeyInCsp = true; string xmlKeys = myRsa.ToXmlString(false); // Öffentlichen Schlüssel veröffentlichen in einer Xml- Datei StreamWriter writer = new StreamWriter(@"..\..\" + NameCspContainer + ".xml"); writer.Write(xmlKeys); writer.Close(); Console.WriteLine("Privater und öffentlicher Schlüssel: \n" + xmlKeys); } // Verschlüsseln eines Textes mit dem öffentlichen Schlüssel aus dem CryptoServiceProvider. static byte[] Encrypt(string NameCspContainer, string txt) { CspParameters csp = new CspParameters(); csp.KeyContainerName = NameCspContainer; RSACryptoServiceProvider myRsa = new RSACryptoServiceProvider(csp); myRsa.PersistKeyInCsp = true; byte[] txtBytes = Encoding.Unicode.GetBytes(txt); return myRsa.Encrypt(txtBytes, false); } // Verschlüsseln eines Textes mit dem öffentlichen Schlüssel aus einer Xml-Datei static byte[] ClientEncrypt(string NameCspContainer, string txt) { RSACryptoServiceProvider myRsa = new RSACryptoServiceProvider(); StreamReader reader = new StreamReader(@"..\..\" + NameCspContainer + ".xml"); string xmlKey = reader.ReadToEnd(); myRsa.FromXmlString(xmlKey); byte[] txtBytes = Encoding.Unicode.GetBytes(txt); return myRsa.Encrypt(txtBytes, false); } // Entschlüsseln eines verschlüsselten Textes mit dem Privaten Schlüssel // aus dem CryptoServiceProvider static string Decrypt(string NameCspContainer, byte[] encryptedBytes) { CspParameters csp = new CspParameters(); csp.KeyContainerName = NameCspContainer; RSACryptoServiceProvider myRsa = new RSACryptoServiceProvider(csp); myRsa.PersistKeyInCsp = true; byte[] txtBytes = myRsa.Decrypt(encryptedBytes, false); string txt = Encoding.Unicode.GetString(txtBytes); return txt; } static void Main(string[] args) { // Demo der Funktionsweise von CspParameter a la CryptoServiceProvider for (int i = 0; i < 2; i++) { RsaKeyAndCspParameter("C1"); Console.WriteLine(); Console.WriteLine(); } for (int i = 0; i < 2; i++) { RsaKeyAndCspParameter("C2"); Console.WriteLine(); Console.WriteLine(); } // Ver- und Entschlüsseln lokal. Schlüssel werden in CryptoServiceProvider - // Schlüsselcontainer "X1" gespeichert byte[] encryptedBytes = Encrypt("X1", "Das Pferd frisst keinen Gurkensalat"); string txt = Decrypt("X1", encryptedBytes); // Verschlüsseln auf Client und Entschlüsseln auf Server. Der Client lädt den // öffentlichen Schlüssel aus einer Xml- Datei // Schlüsselpaar erzeugen RsaKeyAndCspParameter("Y1"); encryptedBytes = ClientEncrypt("Y1", "Der Hund trinkt keine Milch"); txt = Decrypt("Y1", encryptedBytes); } } }
Hash- Codes bilden eine Menge von Informationen eindeutig auf einen binärcode fester Länge ab. Dabei ist es mathematisch nahezu unmöglich, aus einem gegebenen Hash auf die Menge der Texte zu schließen, aus denen er errechnet wurde. Kleine Änderungen im Text führen zu großen Änderungen des Hashwertes.
Verfahren |
Codelänge |
---|---|
SHA1 |
160 bit |
MD5 |
128 bit |
Die digitalen Signaturen kombinieren Public Key- Verschlüsselungsverfahren mit Hashwerten, um die Authenzität eines Dokumentes nachzuweisen. Dabei wird serverseitig der Hash des Dokumentes mit dem privaten Schlüssel verschlüsselt. Das Dokument wird mit dem verschlüsselten Hash erweitert und an den Client gesendet. Die Kombination aus Test und verschlüsselten Hash wird signiertes Dokument genannt. Der Client trennt den verschlüsselten Hash vom Dokument wieder ab. Danach entschlüsselt der Client den Hash mit seinem öffentlichen Schlüssel und vergleicht diesen mit dem aktuellen Hash des Dokumentes. Stimmen beide überein, dann folgt daraus. daß das Dokument während der Übertragung nicht durch einen Dritten geändert wurde.
X 509 ist ein Standard zur Verwaltung von Schlüsseln asymetrischer Verschlüsselungsverfahren im Netz. Entwickelt wurde dieser im Rahmen des X 500 Standards für Netzwerkverzeichnisse (Datenbank zur Verwaltung von Netzwerkresourcen). Die Datensätze mit den Schlüsseln werden Zertifikate genannt. Sie sind Knoten untergeordnet, die als Certificate Authority (CA) bezeichnet werden. Die CA- s sind Dienste, welche neue Zertifikate auf Antrag hin ausstellen, und eine Liste aller bereits ausgestellten Zertifikate verwalten. Jeder Client eines Zertifikatsdienstes kann diesen prüfen lassen, ob ein gegebenes Zertifikat vom CA ausgestellt wurde. Ist der CA vertrauenswürdig, dann kann ein Client so sicherstellen, daß ein Server, der seines Daten mit dem privaten Schlüssel aus dem Zertifikat signiert, ebenfalls vertrauenswürdig ist.