Laden...

C#-Verschlüsselung mit PHP synchronisieren (noch ein Problem...)

Erstellt von Jack_AI vor 15 Jahren Letzter Beitrag vor 15 Jahren 9.568 Views
J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren
C#-Verschlüsselung mit PHP synchronisieren (noch ein Problem...)

Hallo.

Ich möchte gerne von einem C#-Programm einen verschlüsselten MySQL-Befehl an ein PHP-Script schicken. Das Script soll denn Befehl dann entschlüsseln und abarbeiten.

Als Verschlüsselungsmethode möchte ich gerne Rijndael/AES benutzen. Jetzt zu dem Problem: Für C# habe ich einen Rijndael-Algorithmus gefunden, der auch wunderbar funktioniert. Aber ich habe kein entsprechendes Gegenstück für PHP, das verschlüsselte String wieder entschlüsseln kann. Es gibt zwar anscheinend soetwas in einem PHP-Paket namen mcrypt, aber das ist auf meinem Webspace nicht installiert.

Daher meine Fragen an euch, wenn ihr dasselbe Problem hattet oder euch damit auskennt:

  • Wie habt ihr das Problem gelöst? 😉
  • Gibt es einen Rijndael-Algorithmus im Modus "CBC" für PHP? (außer in mcrypt)
  • Gibt es eine andere sichere Möglichkeit, von C# Daten zu verschlüsseln und von PHP entschlüsseln zu lassen?

Danke schon mal im Voraus,
Jack

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Jack_AI,

siehe u.a. Rijndael in C# und PHP

herbivore

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

Das Problem an dem Beispiel ist, dass es eben auf mcrypt basiert. Erkennbar an der Zeile:
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);

Und das habe ich eben nicht.

1.002 Beiträge seit 2007
vor 15 Jahren

Hallo Jack_AI,

du kannst auch selber leichtere, dennoch ausreichend sichere Verschlüsselungalgorithmen wie z.B. RC4 implementieren und die Daten ver- / entschlüsseln lassen (Beispiel in C# http://dotnet-snippets.de/dns/rc4-verschluesselung-SID594.aspx).

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

Hallo m0rius,

ich habe mich mal bisschen zu RC4 erkundigt. Ich glaube in dem Punkt widersprechen sich die deutsche und die englische Wikipedia, da die englische Wikipedia andeutet, dass RC4 recht unsicher ist... falls ich das richtig verstanden habe.

Ich habe das Problem so gelöst, dass ich meinen Provider davon überzeugt habe, mir das Paket mcrypt zu installieren. Anders geht es wohl leider nicht. Zumindest nicht ohne höhere Kryptographie-Kenntnisse.

Jack

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

Hallo noch mal.

Ich bekomme es nicht hin, einen verschlüsselten String von C# in PHP wieder zu entschlüsseln.

Für die C#-Verschlüsselung habe ich den Rijndael-Algorithmus (128 Bit; CBC) von dieser Seite übernommen.

Mein PHP-Entschlüsselungs-Versuch sieht so aus, doch es wird ein anderer Ursprungstext ausgegeben. Das Beispiel mit der Key-Erzeugung habe ich von hier (PDF).


// Beispielwerte

// $data ist der in C# verschlüsselte String "Das ist ein Test!" mit unten stehenden Angaben
$data = "W1i3cV+UNomxirVKygSywBJStgaT16hoffrCqP5swDo=";
// der Key im Klartext
$keyClear = "Passwort";
// der Salt-Wert
$salt = "Salt" 
// ein 16 Zeichen langer IV
$iv = "16ZeichenLaenge!"; 

// Der Versuch den Key so zu erzeugen, wie es das C#-Beispiel macht
$key = mhash_keygen_s2k(MHASH_SHA1, $keyClear, $salt, 16);

$decryptData = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$key,$data,MCRYPT_MODE_CBC,$iv);

// Ausgabe
echo base64_encode($decryptData);

Ich hoffe, ihr könnt mir auf die Sprünge helfen, damit mir PHP wieder meinen String "Das ist ein Test!" ausgibt.

Danke!
Jack

edit: Noch ein Hinweis. Mir ist der Thread aus herbivores Post bekannt. Es handelt sich dabei um einen anderen Rijndael-Algoritmus.

S
120 Beiträge seit 2005
vor 15 Jahren

Actionscript ist die Möglichkeit, postmaterielles Basteln zum Lebensstil zu machen.

Künstliche Intelligenz ist leichter zu ertragen, als natürliche Dummheit!

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

@SunboX:

Danke für die Links. Deine Antwort bezog sich bestimmt auf die Problematik mit dem fehlenden mcrypt-Modul. Die beiden Scripte kenne ich schon. Das Problem mit dem Modul habe ich inzwischen gelöst. Aber jetzt habe ich ein neues Problem... (siehe weiter oben)

Jack

S
120 Beiträge seit 2005
vor 15 Jahren

Ah ok, vll hilfts ja jemanden der über die suche hierher findet. ;o)

Vielleicht hilft dir das hier:

[php]///////////////////////////////////////////////////
// A Encryption/Decryption CLASS with Rijndael 256
// By Ismet Ozalp
// 16.03.2005
// ismetozalp@superonline.com
// Please Do not remove this header
///////////////////////////////////////////////////
class pWord {
var $mykey = "THISisMyKey";
function getEncryptedPass($len){
$pass = $this->makeRandomPassword($len);
return $this->linencrypt($pass);
}
function linencrypt($pass) {
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); //get vector size on ECB mode
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); //Creating the vector
$cryptedpass = mcrypt_encrypt (MCRYPT_RIJNDAEL_256, $this->mykey, $pass, MCRYPT_MODE_ECB, $iv); //Encrypting using MCRYPT_RIJNDAEL_256 algorithm
return $cryptedpass;
}

function lindecrypt($enpass) {  
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);  
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);  
    $decryptedpass = mcrypt_decrypt (MCRYPT_RIJNDAEL_256, $this->mykey, $enpass, MCRYPT_MODE_ECB, $iv); //Decrypting...  
return rtrim($decryptedpass);  
}  
function makeRandomPassword($len) {  
     $salt = "ABCDEFGHJKLMNPRSTUVWXYZ0123456789abchefghjkmnpqrstuvwxyz";  
      srand((double)microtime()*1000000);  
    for($i = 0;$i < $len;$i++) {  
        $num = rand() % 59;  
        $tmp = substr($salt, $num, 1);  
        $pass = $pass . $tmp;  
    }  
return $pass;  
}  

} [/php]

gefunden hier: http://phpclasses.waaf.net/browse/file/8921.html

Ciao SunboX

Actionscript ist die Möglichkeit, postmaterielles Basteln zum Lebensstil zu machen.

Künstliche Intelligenz ist leichter zu ertragen, als natürliche Dummheit!

630 Beiträge seit 2007
vor 15 Jahren

Hallo,

ich kenne mich mit PHP und Verschlüsselung nicht so gut aus, aber gibt es dort eine Möglichkeit dort mit byte-Arrays statt mit Strings zu arbeiten?

Ich könnte mir nähmlich vorstellen dass Informationen beim hin und her konvertieren zu String verloren gehen, weil diese intern möglicherweise anders gespeichert werden.

Gruss
tscherno

To understand recursion you must first understand recursion

http://www.ilja-neumann.com
C# Gruppe bei last.fm

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

@SunboX: Interessanter Code. Danke dafür.

Aber was ich an diesem Code, und auch bei den meisten anderen PHP-Beispielen nicht verstehe ist, wie das mit diesen ganzen Zufallswerten (MCRYPT_RAND, rand()...) funktionieren soll. Schließlich soll die Entschlüsselungsfunktion nicht mit irgendwelchen Zufallswerten rumspielen, sondern meinen Text 1 zu 1 mithilfe meiner Angaben zurückgeben.

Des Weiteren benutzt das Script leider Rijndael im Modus ECB, während mein C#-Rijndael im Modus CBC ist. Ich weiß allerdings nicht, in wie fern sich das genau unterscheidet.

@tscherno: Nein, PHP kennt nicht den Datentyp Byte, geschweige denn das Byte-Array. Ich kann mir vorstellen, dass diese Umkonvertierungen von der Funktion mcrypt_decrypt übernommen werden. Intern basiert PHP ja auf C. Dort sollte es Byte als Datentyp geben.

Jack

630 Beiträge seit 2007
vor 15 Jahren

Hallo Jack_Al,

in dem Code den SunboX gepostet hat, wird der Initialisierungsvektor zufällig erstellt. Das ist nötig um bei gleichem Klartext, unterschiedliche verschlüsselte Texte zu bekommen. Beim entschlüsseln muss natürlich der selbe IV angegeben werden, der beim verschlüsseln verwendet wurde.

Des Weiteren benutzt das Script leider Rijndael im Modus ECB, während mein C#-Rijndael im Modus CBC ist.

Die Klasse RijandaelManaged hat eine Eigenschaft "Mode", mit der kannst du auf ECB umstellen. ECB ist viel unsicherer, weil Blockweise verschlüsselt wird. (mehr dazu hier.)

Zu dem Datentyp-Problem:

In C hat ein char 127 bzw 255 byte (uchar) in C# dagegen 2 (wegen Unicode-Support). Mir ist bewusst das es in PHP kein byte gibt, aber es könnte helfen wenn du auf PHP-Seite ebenfalls mit den Byte-Werten arbeitest.

Gruss
tscherno

To understand recursion you must first understand recursion

http://www.ilja-neumann.com
C# Gruppe bei last.fm

1.002 Beiträge seit 2007
vor 15 Jahren

Um nochmal auf RC4 zurückzukommen: Der Algorithmus hat mehrere Schwachstellen, an denen man ansetzen könnte, um ihn zu knacken, es gibt jedoch sehr einfache Tricks, diese so zu umgehen, dass er wieder ausreichend sicher ist, d.h. im Prinzip nur durch Bruteforcen gebrochen werden kann. (Außerdem gilt der Algorithmus als sicher genug, um ihn als Verschlüsselungsstandard für WLAN zu verwenden ...)

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

Hallo m0rius,

na ja, soweit ich weiß wird er zwar als Standard für WLAN (WEP) eingesetzt, allerdings soll sich WEP von Tools wie Aircrack in den meisten Fällen in unter einer Minute knacken lassen.

Kurzes Zitat dazu aus Wikipedia:

[...]some ways of using RC4 can lead to very insecure cryptosystems such as WEP.

und

[...]today a WEP connection can be cracked with readily available software within minutes.

Ich versuche es also weiterhin mit Rijndael, auch wenn ich es noch immer nicht geschafft habe, es mit PHP zu synchronisieren. Leider.

Jack

1.002 Beiträge seit 2007
vor 15 Jahren

Hallo Jack_AI,

okay, dann war ich in der Hinsicht wohl bei einer falschen Quelle gelandet ...

Aber wo wir gerade beim Thema RC[X] sind: RC6 ist beim NESSIE-Projekt bis unter die Top 5 gekommen und wurde wie Rijndael als "hinreichend sicher" eingestuft.
Sollte das mit der Synchronisierung gar nicht klappen, kannst du es ja mal mit einer selbst geschriebenen RC6-Version probieren.

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

Hallo noch mal,

nach einiger Recherche / Ursachenforschung habe ich entdeckt, dass sich der C#-Rijndael von der PHP-Verschlüsselung insbesondere bei der "Salzung", also dem Hinzufügen eines Salt-Wertes, unterscheidet.

Für den Salt-Wert habe ich zwar dies hier für PHP gefunden:
[php]mhash_keygen_s2k(MHASH_SHA1, $keyClear, $salt, 16);[/php]

Dieser Algorithmus heißt S2K. Der C#-Rijndael benutzt aber einen Salt-Algorithmus aus der Klasse "PasswordDeriveBytes", laut Hilfetext eine Erweiterung des PBKDF1-Algorithmus. Hier scheint in erster Linie das Problem zu liegen. Man muss also einen Salt-Algorithmus finden, der für PHP wie C# gleichermaßen funktioniert. Bisher sieht es so aus, als ob S2K und PBKDF1 nicht für C# wie PHP gleichermaßen vorhanden sind.

Ich habe allerdings noch nicht versucht, C# und PHP mit einem ungesalzenen Passwort miteinander abzugleichen. Das werde ich dann demnächst mal versuchen.

Ansonsten noch ein paar ausstehende Antworten und Ergänzungen:

@m0rius: Dieser Wikipedia-Artikel ist auch ganz interessant. Demnach hat RC6 gar nicht sooo toll abgeschnitten. Ganz zu schweigen davon, dass ich nirgens eine Implementation von RC6 für C# gefunden habe. Also versuche ich es weiterhin mit Rijndael. 😉

@SunboX:
Ich habe den Algorithmus aus deinem letzten Post mal ausprobiert. Merkwürdigerweise habe ich einen anderen Ursprungstext beim Entschlüsseln erhalten. Das war auch bei manch anderen Rijndael-Beispielen für PHP so. Aber vielleicht bin ich auch einfach nur zu doof dafür. ^^

@tscherno:
Danke für die Erklärung! Jetzt habe ich das mit dem IV besser verstanden.

Jack

edit: Mir ist übrigens eingefallen, dass eventuell mein ganzes Konzept einen entscheidenden Fehler hat. Ich will eigentlich Datenbank-Strings in C# verschlüsseln, an PHP senden, um es dort wieder zu entschlüsseln, und dann in eine Datenbank eintragen. Dabei habe ich gar nicht daran gedacht, dass die Verschlüsselung und ihre Parameter im Programm-Code mittels Reflector einsehbar sind. Argh! 🙁

Jack

1.002 Beiträge seit 2007
vor 15 Jahren

Hallo Jack_AI,

Du lässt dich aber auch nicht von der RC[X]-Reihe überzeugen 😉.

Aber ich verstehe nicht ganz, was du mit deinem Konzeptfehler meinst: Selbst, wenn jemand erfahren sollte, wie du die Daten verschlüsselt hast, heißt das noch lange nicht, dass er weiß, was du verschlüsselt hast bzw. was es heißt (ist ja der Sinn der Sache).

<edit>Ah, du meinst, er kann den Key bzw. den Seed erkennen?</edit>

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

Ich habe es jetzt lösen können. Ich habe mich schweren Herzens von dem komplexen Rijndael von weiter oben getrennt und stattdessen diesen mit ein paar Modifikationen übernommen.

Vielleicht kann mir hier jemand mit einem allgemeineren Problem noch helfen:
Ist Rijndael mit 128 Bits, ohne Salt und ohne weitere Iterationen im CBC-Modus sicher genug, damit verschlüsselter Text vor Hackern ohne spezielle Hardware sicher ist?

Grüße,
Jack

J
6 Beiträge seit 2008
vor 15 Jahren

edit: Mir ist übrigens eingefallen, dass eventuell mein ganzes Konzept einen entscheidenden Fehler hat. Ich will eigentlich Datenbank-Strings in C# verschlüsseln, an PHP senden, um es dort wieder zu entschlüsseln, und dann in eine Datenbank eintragen. Dabei habe ich gar nicht daran gedacht, dass die Verschlüsselung und ihre Parameter im Programm-Code mittels Reflector einsehbar sind. Argh! 😦

Hallo Jack.

Du hast da ein ganz entscheidendes "Problem" erkannt. In PHP kann man praktisch nichts verstecken. Von dem Gedanken kannst du umgehend abschied nehmen.

Ich spekuliere jetzt aber einfach mal so vor mich hin. Das ganze Thema klingt für mich irgendwie nach Webservice. Aber unabhängig davon ob du tatsächlich Protokolle wie SOAP oder ähnliches benutzen willst um die Daten an deine Webanwendung zu senden gibt es dafür bereits eine ausgereifte Lösung die sich SSL/TLS nennt.

Wenn du mit deiner Verschlüsselung versuchst Code-Injections zu verhindern hast du relativ sicher einen Designfehler im Konzept. Da du den Umweg über PHP gehst wirst du vermutlich keine Software schreiben um die Datenbank zu verwalten. Überlege dir lieber Wege wie du die Befehle möglichst einfach an PHP senden kannst und den SQL-Query dann in PHP zusammenbaust. So kannst du Angriffe leichter erkennen und abwehren als wenn du einem, wenn auch verschlüsselten, String von außen uneingeschränkt vertraust.

Wenn du aber mit dem Gedanken spielst die gesendeten Daten vor einem legitimen Benutzer zu verstecken wirst du unweigerlich auf Granit beißen. Ebenso wirst du gegen einen Hacker der sich durch andere Sicherheitslöcher Benutzerrechte erschlichen hat keine Chance haben deinen Code zu verstecken.

J
Jack_AI Themenstarter:in
193 Beiträge seit 2007
vor 15 Jahren

Danke für deinen umfassenden Kommentar und deine Bedenken, Jules Papillon.

Ich werde später, wenn mein Sicherheitskonzept umgesetzt ist, es in einem neuen Thread umfangsreich präsentieren.

Grüße,
Jack