DevTrain Startseite Advanced Developers Conference vom 14.-15. Februar 2011  
  
  
SUCHEN:  
ARTIKEL ONLINE: 525   

Kategorien
.NET
Datenbanken
Web
XML

Allgemein
Camp
Foren
Events
Persönliche Einstellungen
Registrieren
Prämien Shop
Kontakt
Impressum
Über DevTrain

Autoren


   Autor: Tobi Ulm Artikel Drucken
        
Daten Verschlüsseln und Signieren mit dem RSA Algorithmus

Verschlüsseln von Daten und Signieren Dieser ist die wichtigste Sache wenn man heute Systeme 
erzeugt welche Datenaustausch betreiben. Erst wird durch den RSA Algorithmus ein Private/Public 
Key Paar erzeugt mit dem dann anschließend eine DatenSignatur erzeugt wird. Zusätzlich werden die 
Daten verschlüsselt.

Der RSA Algorithmus wurde im Jahr 1976 entwickelt, benannt nach seinen Erfindern Rivest, Shamir 
und Adlemann und ist heute der Standard wenn es um Veschlüsselungsalgorithmen geht. Der RSA 
Algorithmus ist ein so genannter Asymmetrischer Verschlüsselungsalgorithmus der sich durch ein 
Schlüsselpaar auszeichnet. Dieses Schlüsselpaar ist durch mathematische Funktionen miteinander 
verknüpft. Viele nutzen sicherlich https. Https ist nichts anderes als eine Verwendung von Asymmetrischen Algorithmus und Symmetrischen Algorithmus.
Werden Daten mit dem Öffentlichen Schlüssel verschlüsselt, kann man diese nur noch mit 
dem Privaten Schlüssel entschlüsseln. Werden die Daten mit dem Privaten Schlüssel verschlüsselt 
ist jeder der einen Öffentlichen Schlüssel besitzt in der Lage die Daten zu entschlüsseln. Ein 
paar Zahlen zu Sicherheit:
    *angenommen wir haben Computer mit 100MHz Pentium Prozessor und 8 MB RAM
    *angenommen wir haben 100 Millionen davon
    *429-bit key 14,5 s
    *512-bit key 22 min.
    *700-bit key 153 Tage
    *1024-bit key 280000 Jahre

Der RSA Algorithmus befindet sich genauso wie alle anderen Verschlüsselungsverfahren im 
System.Security.Cryptography Namespace. Um ein neues Public Key / Private Key Paar zu erzeugen 
muss lediglich von RSACryptoServiceProvider eine neue Instanz erzeugt werden. Dabei wird 
automatisch das Schlüsselpaar erzeugt. Im Konstruktor von RSACryptoServiceProvider() ist es auch 
möglich die Schlüssellänge anzugeben:

RSACryptoServiceProvider m_rsas = new RSACryptoServiceProvider(4096);

 erzeugt also ein neues 
Schlüsselpaar mit 4096 Bit Schlüsseltiefe.

Um die Schlüssel zu verteilen (der Private Key bleibt natürlich bei uns) genügt es die Methode 
ToXmlString() anzusprechen und den XML String in eine Datei zu schreiben.
Wird die Methode ToXmlString(true|false) mit true Argument angesprochen wird der gesamte Schlüssel, also Private 
und Public Key abgelegt. Dies ist für uns wichtig, denn damit sind wird später in der Lage Daten 
die mit dem Public Key von unserem Gegenüber verschlüsselt wurden zu entschlüsseln.

strWrFullKey.Write(RSA.ToXmlString(true));
...
strWrPubKey.Write(RSA.ToXmlString(false));

Die Daten zu signieren ist recht einfach. Was benötigt wird ist das Schlüsselpaar welches im 
vorherigen Schritt als zwei XML Dokumente gesichert wurden. Danach wird einfach die Methode 
SignData() des RSACryptoServiceProvider aufgerufen. Dabei werden als Argumente die zu signierenden 
Daten und der Hashalgorithmus angegeben. (Im Beispiel SH1, möglich wäre auch MD5) Wichtig ist das 
beim Signieren der Daten natürlich der Volle Schlüssel benutzt wird, nur dadurch ist dem gegenüber 
auch nachvollziehbar das die Daten von uns kommen, da nur wir im Besitz des Privaten Schlüssels 
sind.

this.m_RSA.FromXmlString(pubKey);
this.m_signature= this.m_RSA.SignData(this.m_originalData, "SHA1");

Das Überprüfen der Daten anhand der Signatur ist ebenfalls recht einfach. Es muss lediglich der 
RSACryptoServiceProvider mit dem öffentlichen Schlüssel erzeugt werden und die VerifyData() 
Funktion aufgerufen werden der als Argumente die Daten, der  Signaturalgorithmus und die Signatur 
übergeben werden müssen.

this.m_RSA.FromXmlString(pubKey);
bool result = this.m_RSA.VerifyData( this.m_originalData,"SHA1", this.m_signature);

Das Verschlüsseln der Daten geschieht über die Encrypt() Funktion des RSACryptoServiceProvider. 
Dieser Methode werden lediglich die Daten übergeben. Verschlüsselt wird natürlich mit dem 
Öffentlichen Schlüssel nur so sind wir in der Lage sicherzustellen das EIN Empfänger, nämlich wir, 
die Daten entschlüsseln können.

this.txtEncrypted.Text = Convert.ToBase64String(this.m_RSA.Encrypt(this.m_originalData,false) );

Die Daten zu entschlüsseln geschieht ebenfalls über den RSACryptoServiceProvider und dessen 
Decrypt() Methode. Hierbei muss natürlich der volle Schlüssel verwendet werden.

byte[] original = this.m_RSA.Decrypt(byt,false);

Nun das gesamte Beispiel als WinForms Anwendung:


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Security;
using System.Security.Cryptography;
using System.IO;
using System.Text;
namespace CryptoSampleCS{
 public class frmEncryptionSigning : System.Windows.Forms.Form{
  
  #region "Datamember"
  private System.Windows.Forms.Label label1;
  private System.Windows.Forms.Label label2;
  private System.Windows.Forms.TextBox txtOrigData;
  private System.Windows.Forms.TextBox txtAlteredData;
  private System.Windows.Forms.Label label3;
  private System.Windows.Forms.TextBox txtData;
  private System.Windows.Forms.Label label4;
  private System.Windows.Forms.TextBox txtSignature;
  private System.Windows.Forms.Button button1;
  private System.Windows.Forms.Label label5;
  private System.ComponentModel.Container components = null;

 

  byte [] m_originalData;
  byte [] m_alteredData;
  byte [] m_signature;
  private System.Windows.Forms.Button btnSignData;
  private System.Windows.Forms.Button btnVerify;
  private System.Windows.Forms.Button btnVerifyAltered;
  private System.Windows.Forms.Button btnEncrypt;
  private System.Windows.Forms.Button btnDecrypt;
  RSACryptoServiceProvider m_RSA;
  private System.Windows.Forms.TextBox txtEncrypted;
  private System.Windows.Forms.Label label6;
  private System.Windows.Forms.Label label7;
  private System.Windows.Forms.Label label8;
  bool m_blsignature = false;
  #endregion

  #region "ctor"
  public frmEncryptionSigning(){
   InitializeComponent();
  }
  #endregion
  #region "dtor"
  protected override void Dispose( bool disposing ){
   if( disposing ){
    if(components != null){
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }
  #endregion
  #region Vom Windows Form-Designer generierter Code
  /// <summary>
  /// Erforderliche Methode für die Designerunterstützung.
  /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
  /// </summary>
  private void InitializeComponent()
  {
   this.label1 = new System.Windows.Forms.Label();
   this.label2 = new System.Windows.Forms.Label();
   this.txtOrigData = new System.Windows.Forms.TextBox();
   this.txtAlteredData = new System.Windows.Forms.TextBox();
   this.label3 = new System.Windows.Forms.Label();
   this.txtData = new System.Windows.Forms.TextBox();
   this.label4 = new System.Windows.Forms.Label();
   this.txtSignature = new System.Windows.Forms.TextBox();
   this.button1 = new System.Windows.Forms.Button();
   this.btnSignData = new System.Windows.Forms.Button();
   this.btnVerify = new System.Windows.Forms.Button();
   this.btnVerifyAltered = new System.Windows.Forms.Button();
   this.btnEncrypt = new System.Windows.Forms.Button();
   this.btnDecrypt = new System.Windows.Forms.Button();
   this.label5 = new System.Windows.Forms.Label();
   this.txtEncrypted = new System.Windows.Forms.TextBox();
   this.label6 = new System.Windows.Forms.Label();
   this.label7 = new System.Windows.Forms.Label();
   this.label8 = new System.Windows.Forms.Label();
   this.SuspendLayout();
   //
   // label1
   //
   this.label1.Location = new System.Drawing.Point(16, 384);
   this.label1.Name = "label1";
   this.label1.TabIndex = 0;
   this.label1.Text = "Original Daten";
   //
   // label2
   //
   this.label2.Location = new System.Drawing.Point(256, 384);
   this.label2.Name = "label2";
   this.label2.TabIndex = 1;
   this.label2.Text = "Veränderte Daten";
   //
   // txtOrigData
   //
   this.txtOrigData.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
   this.txtOrigData.Location = new System.Drawing.Point(16, 408);
   this.txtOrigData.Multiline = true;
   this.txtOrigData.Name = "txtOrigData";
   this.txtOrigData.ReadOnly = true;
   this.txtOrigData.Size = new System.Drawing.Size(232, 152);
   this.txtOrigData.TabIndex = 2;
   this.txtOrigData.Text = "";
   //
   // txtAlteredData
   //
   this.txtAlteredData.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
   this.txtAlteredData.Location = new System.Drawing.Point(256, 408);
   this.txtAlteredData.Multiline = true;
   this.txtAlteredData.Name = "txtAlteredData";
   this.txtAlteredData.ReadOnly = true;
   this.txtAlteredData.Size = new System.Drawing.Size(248, 152);
   this.txtAlteredData.TabIndex = 3;
   this.txtAlteredData.Text = "";
   //
   // label3
   //
   this.label3.Location = new System.Drawing.Point(8, 16);
   this.label3.Name = "label3";
   this.label3.TabIndex = 4;
   this.label3.Text = "Daten";
   //
   // txtData
   //
   this.txtData.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
   this.txtData.Location = new System.Drawing.Point(8, 48);
   this.txtData.Multiline = true;
   this.txtData.Name = "txtData";
   this.txtData.Size = new System.Drawing.Size(312, 160);
   this.txtData.TabIndex = 5;
   this.txtData.Text = "";
   this.txtData.Validated += new System.EventHandler(this.txtData_Validated);
   //
   // label4
   //
   this.label4.Location = new System.Drawing.Point(512, 384);
   this.label4.Name = "label4";
   this.label4.TabIndex = 6;
   this.label4.Text = "Datensignatur";
   //
   // txtSignature
   //
   this.txtSignature.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
   this.txtSignature.Location = new System.Drawing.Point(512, 408);
   this.txtSignature.Multiline = true;
   this.txtSignature.Name = "txtSignature";
   this.txtSignature.ReadOnly = true;
   this.txtSignature.Size = new System.Drawing.Size(352, 152);
   this.txtSignature.TabIndex = 7;
   this.txtSignature.Text = "";
   //
   // button1
   //
   this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System;
   this.button1.Location = new System.Drawing.Point(176, 240);
   this.button1.Name = "button1";
   this.button1.Size = new System.Drawing.Size(168, 40);
   this.button1.TabIndex = 8;
   this.button1.Text = "Erzeuge Public/Private Key";
   this.button1.Click += new System.EventHandler(this.button1_Click);
   //
   // btnSignData
   //
   this.btnSignData.Enabled = false;
   this.btnSignData.FlatStyle = System.Windows.Forms.FlatStyle.System;
   this.btnSignData.Location = new System.Drawing.Point(176, 280);
   this.btnSignData.Name = "btnSignData";
   this.btnSignData.Size = new System.Drawing.Size(168, 40);
   this.btnSignData.TabIndex = 9;
   this.btnSignData.Text = "Signiere Daten";
   this.btnSignData.Click += new System.EventHandler(this.btnSignData_Click);
   //
   // btnVerify
   //
   this.btnVerify.Enabled = false;
   this.btnVerify.FlatStyle = System.Windows.Forms.FlatStyle.System;
   this.btnVerify.Location = new System.Drawing.Point(344, 240);
   this.btnVerify.Name = "btnVerify";
   this.btnVerify.Size = new System.Drawing.Size(200, 40);
   this.btnVerify.TabIndex = 10;
   this.btnVerify.Text = "Verifiziere Originale Daten";
   this.btnVerify.Click += new System.EventHandler(this.btnVerify_Click);
   //
   // btnVerifyAltered
   //
   this.btnVerifyAltered.Enabled = false;
   this.btnVerifyAltered.FlatStyle = System.Windows.Forms.FlatStyle.System;
   this.btnVerifyAltered.Location = new System.Drawing.Point(344, 280);
   this.btnVerifyAltered.Name = "btnVerifyAltered";
   this.btnVerifyAltered.Size = new System.Drawing.Size(200, 40);
   this.btnVerifyAltered.TabIndex = 11;
   this.btnVerifyAltered.Text = "Verifiziere Veränderte Daten";
   this.btnVerifyAltered.Click += new System.EventHandler(this.btnVerifyAltered_Click);
   //
   // btnEncrypt
   //
   this.btnEncrypt.Enabled = false;
   this.btnEncrypt.FlatStyle = System.Windows.Forms.FlatStyle.System;
   this.btnEncrypt.Location = new System.Drawing.Point(544, 240);
   this.btnEncrypt.Name = "btnEncrypt";
   this.btnEncrypt.Size = new System.Drawing.Size(152, 40);
   this.btnEncrypt.TabIndex = 12;
   this.btnEncrypt.Text = "Verschlüsseln";
   this.btnEncrypt.Click += new System.EventHandler(this.btnEncrypt_Click);
   //
   // btnDecrypt
   //
   this.btnDecrypt.Enabled = false;
   this.btnDecrypt.FlatStyle = System.Windows.Forms.FlatStyle.System;
   this.btnDecrypt.Location = new System.Drawing.Point(544, 280);
   this.btnDecrypt.Name = "btnDecrypt";
   this.btnDecrypt.Size = new System.Drawing.Size(152, 40);
   this.btnDecrypt.TabIndex = 13;
   this.btnDecrypt.Text = "Entschlüsseln";
   this.btnDecrypt.Click += new System.EventHandler(this.btnDecrypt_Click);
   //
   // label5
   //
   this.label5.Location = new System.Drawing.Point(416, 8);
   this.label5.Name = "label5";
   this.label5.Size = new System.Drawing.Size(120, 23);
   this.label5.TabIndex = 14;
   this.label5.Text = "Verschlüsselte Daten";
   //
   // txtEncrypted
   //
   this.txtEncrypted.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
   this.txtEncrypted.Location = new System.Drawing.Point(416, 40);
   this.txtEncrypted.Multiline = true;
   this.txtEncrypted.Name = "txtEncrypted";
   this.txtEncrypted.ReadOnly = true;
   this.txtEncrypted.Size = new System.Drawing.Size(360, 168);
   this.txtEncrypted.TabIndex = 15;
   this.txtEncrypted.Text = "";
   //
   // label6
   //
   this.label6.Location = new System.Drawing.Point(152, 248);
   this.label6.Name = "label6";
   this.label6.Size = new System.Drawing.Size(24, 23);
   this.label6.TabIndex = 16;
   this.label6.Text = "1.";
   //
   // label7
   //
   this.label7.Location = new System.Drawing.Point(320, 88);
   this.label7.Name = "label7";
   this.label7.Size = new System.Drawing.Size(16, 23);
   this.label7.TabIndex = 17;
   this.label7.Text = "2.";
   //
   // label8
   //
   this.label8.Location = new System.Drawing.Point(152, 288);
   this.label8.Name = "label8";
   this.label8.Size = new System.Drawing.Size(8, 23);
   this.label8.TabIndex = 18;
   this.label8.Text = "3.";
   //
   // frmEncryptionSigning
   //
   this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
   this.ClientSize = new System.Drawing.Size(888, 582);
   this.Controls.Add(this.label8);
   this.Controls.Add(this.label7);
   this.Controls.Add(this.label6);
   this.Controls.Add(this.txtEncrypted);
   this.Controls.Add(this.label5);
   this.Controls.Add(this.btnDecrypt);
   this.Controls.Add(this.btnEncrypt);
   this.Controls.Add(this.btnVerifyAltered);
   this.Controls.Add(this.btnVerify);
   this.Controls.Add(this.btnSignData);
   this.Controls.Add(this.button1);
   this.Controls.Add(this.txtSignature);
   this.Controls.Add(this.label4);
   this.Controls.Add(this.txtData);
   this.Controls.Add(this.label3);
   this.Controls.Add(this.txtAlteredData);
   this.Controls.Add(this.txtOrigData);
   this.Controls.Add(this.label2);
   this.Controls.Add(this.label1);
   this.Name = "frmEncryptionSigning";
   this.Text = "Encryption/ Data Signing";
   this.ResumeLayout(false);

  }
  #endregion

  private void button1_Click(object sender, System.EventArgs e) {
   RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();//RSACryptoServiceProvider(4096):=Schlüsseltiefe auf 4096
   System.IO.StreamWriter strWrFullKey = new StreamWriter(Application.StartupPath.ToString()+ System.IO.Path.DirectorySeparatorChar + "FullKey.xml");
   strWrFullKey.Write(RSA.ToXmlString(true));
   strWrFullKey.Close();
   System.IO.StreamWriter strWrPubKey = new StreamWriter(Application.StartupPath.ToString() + System.IO.Path.DirectorySeparatorChar + "PublicKey.xml");
   strWrPubKey.Write(RSA.ToXmlString(false));
   strWrPubKey.Close();
   MessageBox.Show("Keys wurden erzeugt und in XML Files abgelegt!");
   this.m_blsignature = true;

  }

  private void txtData_Validated(object sender, System.EventArgs e) {
   if ( !this.txtData.Text.Equals(string.Empty) ){
    UnicodeEncoding ByteConverter = new UnicodeEncoding();
    this.m_originalData = ByteConverter.GetBytes(this.txtData.Text);
    this.txtOrigData.Text = this.formatBytes(this.m_originalData);
    this.m_alteredData = new byte[this.m_originalData.Length];
    this.m_originalData.CopyTo(this.m_alteredData, 0);
    this.m_alteredData[0] = 42;
    this.txtAlteredData.Text = this.formatBytes( this.m_alteredData );
    if ( this.m_blsignature ) {
     this.btnSignData.Enabled = true;
    }
    else{
     this.btnSignData.Enabled = false;
    }

   }
   this.btnEncrypt.Enabled = true;
   this.btnDecrypt.Enabled = false;
   this.btnVerify.Enabled = false;
   this.btnVerifyAltered.Enabled = false;
  }

  private string formatBytes(byte[] data) {
   StringBuilder output = new StringBuilder();
   for (int i = 0; i < data.Length; i++) {
    output.Append(" " + data[i].ToString("X2"));
    if ((i % 8 == 7) && (i < data.Length - 1))
     output.Append("\r\n");
   }
   return output.ToString();
  }

  private void btnSignData_Click(object sender, System.EventArgs e) {
   this.m_RSA = new RSACryptoServiceProvider();
   System.IO.StreamReader srRdPubKey = new StreamReader(Application.StartupPath.ToString() + System.IO.Path.DirectorySeparatorChar + "FullKey.xml");
   string pubKey = srRdPubKey.ReadToEnd();
   srRdPubKey.Close();
   this.m_RSA.FromXmlString(pubKey);
   this.m_signature= this.m_RSA.SignData(this.m_originalData, "SHA1");
   this.txtSignature.Text = this.formatBytes(this.m_signature);
   MessageBox.Show("Signatur wurde erfolgreich erzeugt!");
   this.btnVerify.Enabled = true;
   this.btnVerifyAltered.Enabled = true;
  }

  private void btnEncrypt_Click(object sender, System.EventArgs e) {
   this.m_RSA = new RSACryptoServiceProvider();
   System.IO.StreamReader srRdPubKey = new StreamReader(Application.StartupPath.ToString() + System.IO.Path.DirectorySeparatorChar + "PublicKey.xml");
   string pubKey = srRdPubKey.ReadToEnd();
   srRdPubKey.Close();
   this.m_RSA.FromXmlString(pubKey);
   this.txtEncrypted.Text = Convert.ToBase64String(this.m_RSA.Encrypt(this.m_originalData,false) );
   this.txtData.Text = string.Empty;
   this.btnEncrypt.Enabled = false;
   this.btnDecrypt.Enabled = true;
  }

  private void btnDecrypt_Click(object sender, System.EventArgs e) {
   this.m_RSA = new RSACryptoServiceProvider();
   System.IO.StreamReader srRdFulley = new StreamReader(Application.StartupPath.ToString() + System.IO.Path.DirectorySeparatorChar + "FullKey.xml");
   string fullKey = srRdFulley.ReadToEnd();
   srRdFulley.Close();
   this.m_RSA.FromXmlString(fullKey);
   byte[] byt;
   UnicodeEncoding ByteConverter = new UnicodeEncoding();
   byt =  Convert.FromBase64String( this.txtEncrypted.Text);
   byte[] original = this.m_RSA.Decrypt(byt,false);
   this.txtData.Text = ByteConverter.GetString(original);
   this.btnDecrypt.Enabled = false;
   this.btnEncrypt.Enabled = true;
   this.txtEncrypted.Text = string.Empty;
  }

  private void btnVerify_Click(object sender, System.EventArgs e) {
   if (this.m_signature != null) {
    this.m_RSA = new RSACryptoServiceProvider();
    System.IO.StreamReader srRdPubKey = new StreamReader(Application.StartupPath.ToString() + System.IO.Path.DirectorySeparatorChar + "PublicKey.xml");
    string pubKey = srRdPubKey.ReadToEnd();
    srRdPubKey.Close();
    this.m_RSA.FromXmlString(pubKey);
    bool result = this.m_RSA.VerifyData( this.m_originalData,"SHA1", this.m_signature);
    if (result){
     MessageBox.Show("Daten wurden erfolgreich gegen die Signatur verifiziert");
    }
    else{
     MessageBox.Show("Daten konnten nicht erfolgreich gegen die Signatur verifiziert werden.");
    }
   }
   else{
    MessageBox.Show("Keine signatur gefunden!");
   }
  }

  private void btnVerifyAltered_Click(object sender, System.EventArgs e) {
   if (this.m_signature != null) {
    this.m_RSA = new RSACryptoServiceProvider();
    System.IO.StreamReader srRdPubKey = new StreamReader(Application.StartupPath.ToString() + System.IO.Path.DirectorySeparatorChar + "PublicKey.xml");
    string pubKey = srRdPubKey.ReadToEnd();
    srRdPubKey.Close();
    this.m_RSA.FromXmlString(pubKey);
    bool result = this.m_RSA.VerifyData( this.m_alteredData,"SHA1", this.m_signature);
    if (result){
     MessageBox.Show("Daten wurden erfolgreich gegen die Signatur verifiziert");
    }
    else{
     MessageBox.Show("Daten konnten nicht erfolgreich gegen die Signatur verifiziert werden.");
    }
   }
   else{
    MessageBox.Show("Keine signatur gefunden!");
   }
  }

  [STAThread]
  static void Main() {
   Application.EnableVisualStyles();
   Application.Run(new frmEncryptionSigning());
  }
 }
}

 


DevTrain Camp - Schneller zum .NET 3.5 Developer
 
Verwandte Artikel      Verlinkte Dokumente
    Keine verknüpften Dokumente
    Keine Links vorhanden

  Erfasst am: 18.11.2004
  Gültig bis: 16.02.2005
17 Ratings
Bewertung: 49,4%
schlecht    sehr gut  

 
© Copyright 2007 ppedv AG