Verschlüsselung mit öffentlichem Schlüssel
Frank Dzaebel, erstellt am: 5.05.2007, zuletzt geändert: 5.05.2007
Kategorie:Kryptografie, .NET-Version:2.0, [Download]

Erläuterung eines Beispiel-Szenarios von asymmetrischer Verschlüsselung mit Hilfe des RSACryptoServiceProvider's unter Nutzung eines privaten und eines öffentlichen Schlüssels.


Siehe auch:
- Überprüfen und Erstellen von Signaturen (in diesem Dokument)
- Arbeiten mit Zertifikaten in .NET 2.0 – Teil 1
Der Artikel beschreibt, wie man prinzipiell mit X.509 Zertifikaten in .NET 2.0 umgeht. Es wird der Zugriff auf den Zertifikats-Speicher, der Umgang mit Zertifikaten, deren Prüfung sowie die kryptografischen Operationen, die mit Zertifikaten durchgeführt werden können, erläutert.
- Arbeiten mit Zertifikaten in .NET 2.0 – Teil 2
In diesem Teil werden die kryptografischen Operationen, die mit einem Zertifikat und dem dazugehörigen privaten Schlüssel durchgeführt werden können, beleuchtet.
- MSDN Solve – Security How To’s und CodeClips

using System;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace RsaPrivatePublic
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    // Mit dem öffentlichen Schlüssel verschlüsselte Daten können nur mit dem privaten Schlüssel 
    // entschlüsselt werden, und mit dem privaten Schlüssel signierte Daten können nur mit dem 
    // öffentlichen Schlüssel überprüft werden. 
    // http://MSDN.microsoft.com/de-de/library/92f9ye3s.aspx

    private void Form1_Load(object sender, EventArgs e)
    {
      string privateKey; string publicKey;
      AliceErstelltPrivatenUndPublicKey(out privateKey, out publicKey);
      // Alice sendet Bob den publicKey zu
      byte[] verschlüsselteNachricht = BobsVerschlüsselteNachricht(publicKey);
      AliceEntschlüsselt(verschlüsselteNachricht, privateKey);
    }

    private void AliceEntschlüsselt(byte[] verschlüsselteNachricht, string privateKey)
    {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
      rsa.FromXmlString(privateKey);
      byte[] bytesDecrypted = rsa.Decrypt(verschlüsselteNachricht, false);
      MessageBox.Show("Alice liest die Nachricht:\r\n" +
        Encoding.ASCII.GetString(bytesDecrypted));
    }

    private static void AliceErstelltPrivatenUndPublicKey(
      out string privateKey, out string publicKey)
    {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
      privateKey = rsa.ToXmlString(true); publicKey = rsa.ToXmlString(false);
    }

    private byte[] BobsVerschlüsselteNachricht(string publicKey)
    {
      string bobsGeheimeNachricht = "Hi Alice,
        wie geht's? ciao Bob";
      byte[] bobsByteText = Encoding.ASCII.GetBytes(bobsGeheimeNachricht);
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
      rsa.FromXmlString(publicKey);
      return rsa.Encrypt(bobsByteText, false);
    }
  }
}
Überprüfen und Erstellen von Signaturen using System; using System.Text; using System.Security.Cryptography; using System.Windows.Forms; namespace RSA_SignaturBeispiel { class SignaturBeispiel { ///<summary>Der Sender</summary> static Alice alice = new Alice(); ///<summary>Der Empfänger</summary> static Bob bob = new Bob(); /// <summary>Startet ein Beispiel für Signatur-Überprüfungs-Verfahren</summary> static public void Start() { byte[] asciiOriginal, verschlüsselt, signatur; // Eine kleine Menge von Daten wählen, die verschlüsselt werden string original = "Mein Text"; // Daten in ein byte[] Array konvertieren asciiOriginal = ASCIIEncoding.ASCII.GetBytes(original); // Daten mit dem öffentlichen Schlüssel des Empfängers(Bob) verschlüsseln. verschlüsselt = alice.EncryptData(bob.ÖffentlicheParameter, asciiOriginal); // Die verschlüsselten Daten hash'en und eine Signatur aus dem Hash // mit dem privaten Schlüssel des Senders(Alice) erzeugen. signatur = alice.HashUndSignieren(verschlüsselt); MessageBox.Show("Original:" + original + " (Signatur erstellt)"); // Bob überprüft, ob die Signatur authentisch (bzgl. Alice) ist, // indem der öffentliche Schlüssel von Alice (dem Sender) benutzt wird. if (bob.ÜberprüfeHash(alice.PublicParameters, verschlüsselt, signatur)) //Entschlüsselt die Daten über den privaten Key des Empfängers(Bob) bob.EntschlüsseleDaten(verschlüsselt); else MessageBox.Show("Ungültige Signatur"); } } /// <summary>Alice, in diesem Szenario der Sender</summary> class Alice { RSAParameters rsaÖffentlicheParameter; RSAParameters rsaPrivateParameter; public Alice() { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); // Öffentlichen und privaten Schlüssel-Daten erzeugen rsaPrivateParameter = rsa.ExportParameters(true); rsaÖffentlicheParameter = rsa.ExportParameters(false); } /// <summary>Öffentliche Eigenschaften des von Alice erstellten /// RSACryptoServiceProvider [rsa.ExportParameters(false)]</summary> public RSAParameters PublicParameters { get { return rsaÖffentlicheParameter; } } /// <summary> Erzeugt manuell einen Hash und signiert diesen Hashwert /// dann über RSA.SignHash mit dem SHA1 Algorithmus.</summary> public byte[] HashUndSignieren(byte[] encrypted) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); SHA1Managed hash = new SHA1Managed(); byte[] gehashteDaten; rsa.ImportParameters(rsaPrivateParameter); gehashteDaten = hash.ComputeHash(encrypted); return rsa.SignHash(gehashteDaten, CryptoConfig.MapNameToOID("SHA1")); } ///<summary> Verschlüsselt über die öffentlichen Schlüsseldaten/Parameter.</summary> public byte[] EncryptData(RSAParameters rsaParameter, byte[] zuVerschlüsseln) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.ImportParameters(rsaParameter); return rsa.Encrypt(zuVerschlüsseln, false); } } /// <summary>Bob, in diesem Szenario der Empfänger</summary> class Bob { /// <summary>Die öffentlichen RSA-Parameterwerte (normal: Exponent,Modulus)</summary> RSAParameters rsaÖffentlicheParamter; /// <summary>Die privaten RSA-Parameterwerte (D, DP, DQ, InverseQ, P) + öffentliche</summary> RSAParameters rsaPrivateParameter; public Bob() { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); // Öffentliche und private Schlüsseldaten erzeugen. rsaPrivateParameter = rsa.ExportParameters(true); rsaÖffentlicheParamter = rsa.ExportParameters(false); } /// <summary>Die öffentlichen RSA-Parameterwerte (normal: Exponent,Modulus)</summary> public RSAParameters ÖffentlicheParameter { get { return rsaÖffentlicheParamter; } } /// <summary> Berechnet den Hash der signierten Daten und gibt das /// Ergebnis der Überprüfung dieses Hashs zurück (RSA.VerifyHash).</summary> public bool ÜberprüfeHash(RSAParameters rsaParameter, byte[] signierteDaten, byte[] signatur) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); SHA1Managed hash = new SHA1Managed(); byte[] gehashteDaten; rsa.ImportParameters(rsaParameter); gehashteDaten = hash.ComputeHash(signierteDaten); return rsa.VerifyHash(gehashteDaten, CryptoConfig.MapNameToOID("SHA1"), signatur); } /// <summary>Entschlüsselt die Daten über den privaten Key des Empfängers(Bob)</summary> public void EntschlüsseleDaten(byte[] verschlüsselt) { byte[] entschlüsselt; string entschlüsselterText; ASCIIEncoding meinAscii = new ASCIIEncoding(); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.ImportParameters(rsaPrivateParameter); entschlüsselt = rsa.Decrypt(verschlüsselt, false); entschlüsselterText = Encoding.ASCII.GetString(entschlüsselt); MessageBox.Show("Entschlüsselter Text:" + entschlüsselterText); } } }