Hallo,
ich sende einen Stream an PHP und lese diesen aus. Dieser Stream ist verschüsselt. benutzt wurde Rijndael.
Mein Problem ist, dass ich in PHP nicht wirklich firm bin und ich das De und EnCoding auch auf PHP Seite benötige.
Meine Frage ist nun: Was mache ich auf PHP Seite falsch, wenn ich den Stream durch das Entschlüsseln jage? Ich denke wennich den Initialsierungsvektor baue, mache ich den Fehler. (GetKeyByKeyString)
Wäre Super, wenn jemand da mal mit den Augen drüberfliegt. Habe versucht, bestmöglich zu dokumentieren.
Chris
----
Mein PHP Code:
Das Gegenstück in C# sieht so aus:
ich sende einen Stream an PHP und lese diesen aus. Dieser Stream ist verschüsselt. benutzt wurde Rijndael.
Mein Problem ist, dass ich in PHP nicht wirklich firm bin und ich das De und EnCoding auch auf PHP Seite benötige.
Meine Frage ist nun: Was mache ich auf PHP Seite falsch, wenn ich den Stream durch das Entschlüsseln jage? Ich denke wennich den Initialsierungsvektor baue, mache ich den Fehler. (GetKeyByKeyString)
Wäre Super, wenn jemand da mal mit den Augen drüberfliegt. Habe versucht, bestmöglich zu dokumentieren.
Chris
----
Mein PHP Code:
PHP-Code:
class Registrierung
{
private $xmlPlain;
private $xmlValid;
private $db;
private $key;
private $keyIv;
private $keySize;
private $blockSize;
public function Registrierung($sendData)
{
$this->xmlPlain = simplexml_load_string($sendData);
$this->db = new DBAccess(); // Eigene Klasse für DB Zugriff
$this->key = "3EisFürHannah";
$this->keyIv = "3EisFürHannah";
$this->keySize = 256;
$this->blockSize = 256;
// Registrieren
$this->ExecuteReg();
}
private Function ExecuteReg()
{
$decoded = $this->xmlPlain->Registration;
// Den Initialsierungsvektor bau ich selbst ....
//$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$iv = $this->GetKeyByKeyString($this->keyIv);
$key = $this->GetKeyByKeyString($this->key);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, , $decoded, MCRYPT_MODE_ECB, $iv);
return $decrypted;
}
private function GetKeyByKeyString($strKeyString)
{
// die Schluesselgroesse in Byte entspricht einer Unicodestringlaenge von Keysize / 16
$iKeyLen = $this->keySize / 16;
// Password auf die Schluessellaenge von 256bit bringen
if ($strKeyString.Length > iKeyLen) $strKeyString = substr(strKeyString, 0, iKeyLen); // zu lang, abhacken
if ($strKeyString.Length < iKeyLen) $strKeyString = str_pad(strKeyString, iKeyLen, '#'); // zu kurz, auffüllen
echo "\r\n KEY: ".$strKeyString;
// auf 256bit getrimmtes Password in einen Unicodekonformen Schluessel wandeln -jedoch kommt hier immer Gülle raus - wieso nur?
echo $strKeyString;
return $strKeyString;
}
}
PHP-Code:
public class EnviCrypt
{
private readonly int _keySize = 256;
private readonly int _blockSize = 256;
private string _ipNichtErmittelbar = "IP Nicht ermittelbar.";
private string _medienNichtErmittelbar = "Medien nicht ermittelbar.";
private const string iv = "3EisFürHannah";
private const string key = "3EisFürHannah";
/// <summary>
/// Konstruktor.
/// </summary>
public EnviCrypt()
{
GetIVByKeyString(iv);
GetKeyByKeyString(key);
}
/// <summary>
/// Passwortaufbereitung
/// </summary>
private byte[] GetKeyByKeyString(string strKeyString)
{
// die Schluesselgroesse in Byte entspricht einer Unicodestringlaenge von Keysize / 16
int iKeyLen = _keySize / 16;
// Password auf die Schluessellaenge von 256bit bringen
if (strKeyString.Length > iKeyLen) strKeyString = strKeyString.Substring(0, iKeyLen); // zu lang, abhacken
if (strKeyString.Length < iKeyLen) strKeyString = strKeyString.PadRight(iKeyLen, '#'); // zu kurz, auffüllen
// auf 256bit getrimmtes Password in einen Unicodekonformen Schluessel wandeln
return Encoding.Unicode.GetBytes(strKeyString);
}
/// <summary>
/// Initialisierungsvektor
/// </summary>
private byte[] GetIVByKeyString(string strKeyString)
{
// Initialisierungvektor ist gleich dem Schluessel.
// RIJANDAL benötigt dies, hier wird nur das Passwort
// als Bytefolge benutzt, könnte man ausbauen.
return GetKeyByKeyString(strKeyString);
}
/// <summary>
/// verschlusseln
/// </summary>
public string EncryptString(string strInputString)
{
return EncryptString(strInputString, key);
}
/// <summary>
/// verschlusseln
/// </summary>
public string EncryptString(string strInputString, string strKeyString)
{
try
{
// den Schluessel und den Initalisierungsvektor holen
byte[] abyKey = GetKeyByKeyString(strKeyString);
byte[] abyIV = GetIVByKeyString(strKeyString);
// hier kommt dann der Encryptedte String rein
string strResult = "";
// erzeugen eines Rijndael-Crypthographieobjektes
RijndaelManaged rij = new RijndaelManaged();
rij.BlockSize = _blockSize;
rij.KeySize = _keySize;
// Encodierung funktioniert auf Basis von Streams, d.h....
// ...einen Stream fuer die Eingabe erstellen und mit encodierenden String versorgen...
MemoryStream inStream = new MemoryStream(Encoding.Unicode.GetBytes(strInputString));
// ...einen Stream fuer die Ausgabe erstellen, da wo der encryptete String rein soll...
MemoryStream outStream = new MemoryStream();
// ...sowie der Crypthographistream; der stellt die Verbindung zwischen den beiden Streams
// her und erledigt den Encryptvorgang
// hier muss jetzt auch das Encryptobjekt uebergeben werden, damit der Stream weiss,
// wie er encrypten soll
CryptoStream csStream = new CryptoStream(outStream, rij.CreateEncryptor(abyKey, abyIV),
CryptoStreamMode.Write);
// den Inputstream bis zum Ende auslesen und an den Cryptographistream uebergeben
// ACHTUNG: die Methode ReadByte gibt kein Byte sondern ein int zurueck,
// da -1 als Rueckgabewert moeglich!
int iData;
while ((iData = inStream.ReadByte()) != -1) csStream.WriteByte((byte)iData);
// aufraeumen
csStream.Close();
outStream.Close();
inStream.Close();
// fuer abschliessende Operationen brauchen wir den Stream komplett als Array
byte[] abyBuffer = outStream.ToArray();
// der gecryptete String enthaelt keine sinnvollen Zeichen mehr,
// d.h. wenn man den String als Text in eine Datei schreiben will gibt es Probleme
// daher wird hier jedes Byte als seine Hexadezimalzahlentsprechung geschrieben.
// z.B. 255 als "FF" in den String geschrieben
foreach (byte singleByte in abyBuffer) strResult += singleByte.ToString("X2");
// endlich fertig, unsere Funktion hat aus einem sinnvollen String eine
// encryptete Zeichenfolge im Format "FFAAEA01..." etc. erzeugt
return strResult;
}
catch (Exception ex)
{
throw new Exception("Verschlüsselung fehlgeschlagen " + ex.Message);
}
}
/// <summary>
/// Entschlüsseln
/// </summary>
public string DecryptString(string strInputString, string strKeyString)
{
try
{
// den Schluessel und den Initalisierungsvektor holen
byte[] abyKey = GetKeyByKeyString(strKeyString);
byte[] abyIV = GetIVByKeyString(strKeyString);
// erzeugen eines Rijndael-Crypthographieobjektes
RijndaelManaged rij = new RijndaelManaged();
rij.BlockSize = _blockSize;
rij.KeySize = _keySize;
// der Stream in den wir den nicht lesbaren Encrypteten String schreiben...
MemoryStream inStream = new MemoryStream();
// ...was genau hier geschieht, die Zeichen des Strings hatten wir als Hexadezimalzahlen,
// jetzt muessen daraus wieder die Bytes werden z.B. aus "FF" das Byte mit dem Wert 255
for (int i = 0; i < strInputString.Length; i += 2)
inStream.WriteByte(byte.Parse(strInputString.Substring(i, 2),
System.Globalization.NumberStyles.AllowHexSpecifier));
// nach dem Vollschreiben steht der Lese/Schreibzeiger auf dem Ende des Stream,
// fuer weitere Aktionen setzen wir ihn wieder an den Anfang
inStream.Position = 0;
// jetzt brauchen wir noch einen Ausgabestream und einen Cryptographiestream
// der Input und Output ueber den Cryptographiealgorithmus miteinander verbindet
MemoryStream outStream = new MemoryStream();
CryptoStream csStream = new CryptoStream(inStream, rij.CreateDecryptor(abyKey, abyIV),
CryptoStreamMode.Read);
// hier wird jetzt aus dem Crypthographiestream (der den Inputstream als Quelle hat)
// das rueckgewandeltet Byte gelesen
// ACHTUNG: die Methode ReadByte gibt kein Byte sondern ein int zurueck,
// da -1 als Rueckgabewert moeglich!
int iData;
while ((iData = csStream.ReadByte()) != -1) outStream.WriteByte((byte)iData);
// aufraeumen
csStream.Close();
outStream.Close();
inStream.Close();
// wir wohlen am Ende einen String haben, also den Stream als Array abbilden
byte[] abyBuffer = outStream.ToArray();
// Bytes sollen als Unicodezeichen interpretiert werden
return Encoding.Unicode.GetString(abyBuffer);
}
catch (Exception ex)
{
throw new Exception(ex.Message + "\n\nGrund: wahrscheinlich falsches Password.");
}
}
}
}
Kommentar