![]() |
Delphi <-> PHP Encryption / Decryption
Ich habe bis BDS 2006 DCPCrypt benutzt, leider in Delphi 2009 nicht mehr verwendbar da nicht unicode-fähig. Jetzt habe ich DEC 5.2 gefunden und es funzt in Delphi einwandfrei. Jedoch kann ich nicht mit PHP kommunizieren. Habe schon alles ausprobiert :-(
/* * Verschlüsselung von Daten mit Passwort * * Verschlüsselt Daten mit RIJNDAEL (128bit). * Gibt bei Erfolg verschlüsselten Text zurück. * * @param data Eingabetext * * @return verschlüsselter Text */ function encrypt($data, $key) { $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, 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_128, $key, $data, MCRYPT_MODE_ECB, $iv); //Encrypting using MCRYPT_RIJNDAEL_256 algorithm return $cryptedpass; /* $str = mcrypt_cbc(MCRYPT_RIJNDAEL_128,$key,$data,MCRYPT_E NCRYPT,$iv); return $str; */ } /* * Entschlüsselung von Daten mit Passwort * * Entschlüsselt Daten mit RIJNDAEL (128bit). * Gibt bei Erfolg entschlüsselten Text zurück. * * @param data Eingabetext * * @return entschlüsselter Text */ function decrypt($data, $key) { $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $decryptedpass = mcrypt_decrypt (MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB, $iv); //Decrypting... return rtrim($decryptedpass); /* $str = mcrypt_cbc(MCRYPT_RIJNDAEL_128,$key,$data,MCRYPT_D ECRYPT,$iv); // bis zum ersten 0-Byte $len = strlen($str); for ($i=0; $i<$len; $i++) { if (ord($str[$i]) == 0) { $str = substr($str, 0, $i); break; } } return $str; */ }
Delphi-Quellcode:
Wer kann mir damit helfen?
var
ACipherClass: TDECCipherClass = TCipher_Rijndael; ACipherMode: TCipherMode = cmECBx; AHashClass: TDECHashClass = THash_MD5; ATextFormat: TDECFormatClass = TFormat_MIME64; AKDFIndex: LongWord = 1; function Encrypt(const AText: String; const APassword: String): String; overload; var ASalt: Binary; AData: Binary; APass: Binary; begin MainForm.WriteLog('encrypt(): T=' + aText + ' P=' + APassword); with ValidCipher(ACipherClass).Create, Context do try ASalt := RandomBinary(16); APass := ValidHash(AHashClass).KDFx(APassword[1], Length(APassword) * SizeOf(APassword[1]), ASalt[1], Length(ASalt), KeySize, TFormat_Copy, AKDFIndex); Mode := ACipherMode; SetLength(AData, Length(AText) * SizeOf(AText[1])); Encode(AText[1], AData[1], Length(AData)); Result := ValidFormat(ATextFormat).Encode(ASalt + AData + CalcMAC); finally Free; ProtectBinary(ASalt); ProtectBinary(AData); ProtectBinary(APass); end; MainForm.WriteLog('encrypt(): R=' + Result); end; function Encrypt(const AText: WideString; const APassword: WideString): WideString; overload; var ASalt: Binary; AData: Binary; APass: Binary; begin with ValidCipher(ACipherClass).Create, Context do try ASalt := RandomBinary(16); APass := ValidHash(AHashClass).KDFx(APassword[1], Length(APassword) * SizeOf(APassword[1]), ASalt[1], Length(ASalt), KeySize, TFormat_Copy, AKDFIndex); Mode := ACipherMode; Init(APass); SetLength(AData, Length(AText) * SizeOf(AText[1])); Encode(AText[1], AData[1], Length(AData)); Result := ValidFormat(ATextFormat).Encode(ASalt + AData + CalcMAC); finally Free; ProtectBinary(ASalt); ProtectBinary(AData); ProtectBinary(APass); end; MainForm.WriteLog('encrypt(): ' + Result); end; function Decrypt(const AText: String; const APassword: String): String; overload; var ASalt: Binary; AData: Binary; ACheck: Binary; APass: Binary; ALen: Integer; begin with ValidCipher(ACipherClass).Create, Context do try ASalt := ValidFormat(ATextFormat).Decode(AText); ALen := Length(ASalt) - 16 - BufferSize; AData := System.Copy(ASalt, 17, ALen); ACheck := System.Copy(ASalt, ALen + 17, BufferSize); SetLength(ASalt, 16); APass := ValidHash(AHashClass).KDFx(APassword[1], Length(APassword) * SizeOf(APassword[1]), ASalt[1], Length(ASalt), KeySize, TFormat_Copy, AKDFIndex); Mode := ACipherMode; Init(APass); SetLength(Result, ALen div SizeOf(AText[1])); Decode(AData[1], Result[1], ALen); if ACheck <> CalcMAC then raise Exception.Create('Invalid data'); finally Free; ProtectBinary(ASalt); ProtectBinary(AData); ProtectBinary(ACheck); ProtectBinary(APass); end; end; function Decrypt(const AText: WideString; const APassword: WideString): WideString; overload; var ASalt: Binary; AData: Binary; ACheck: Binary; APass: Binary; ALen: Integer; begin with ValidCipher(ACipherClass).Create, Context do try ASalt := ValidFormat(ATextFormat).Decode(AText); ALen := Length(ASalt) - 16 - BufferSize; AData := System.Copy(ASalt, 17, ALen); ACheck := System.Copy(ASalt, ALen + 17, BufferSize); SetLength(ASalt, 16); APass := ValidHash(AHashClass).KDFx(APassword[1], Length(APassword) * SizeOf(APassword[1]), ASalt[1], Length(ASalt), KeySize, TFormat_Copy, AKDFIndex); Mode := ACipherMode; Init(APass); SetLength(Result, ALen div SizeOf(AText[1])); Decode(AData[1], Result[1], ALen); if ACheck <> CalcMAC then raise Exception.Create('Invalid data'); finally Free; ProtectBinary(ASalt); ProtectBinary(AData); ProtectBinary(ACheck); ProtectBinary(APass); end; end; |
Re: Delphi <-> PHP Encryption / Decryption
Hier nochmal der PHP-Code zum testen:
// User entschlüsseln $u1 = base64_encode(encrypt('abc', $global_crypt)); echo 'u1: '.$u1."\n"; $p1 = base64_encode(encrypt('xyz', $u1)); echo 'p1: '.$p1."\n"; $p1 = base64_encode(base64_encode(encrypt($p1, $global_crypt))); echo 'p1: '.$p1."\n\n"; // Passwort entschlüsseln echo 'p2: '.$p1."\n"; $p2 = decrypt(base64_decode(base64_decode($p1)), $global_crypt); echo 'p2: '.$p2."\n"; $p2 = decrypt(base64_decode($p2), $u1); echo 'p2: '.$p2."\n"; $u2 = decrypt(base64_decode($u1), $global_crypt); echo 'u2: '.$u2."\n\n"; So, und hier teste ich mit der Übergabe von Delphi (DEC): $user = '6l7GU7LYt04pVHc/00d7JjB/1bjCRn5n18SPwc/AK77qEUtTAEU='; $c_user = decrypt(base64_decode($user), $global_crypt); echo 'u1: '.$c_user."\n\n"; |
Re: Delphi <-> PHP Encryption / Decryption
Hi TDS,
erstmal ein herzliches Willkommen in der DP von mir! Ich habe leider im Moment vor lauter Arbeit nicht viel Zeit, deswegen kann ich mich (noch) nicht genau mit dem Problem befassen bzw. habe den Code nur kurz überflogen. :oops: Ein vielleicht hilfreicher Link zu einem ähnlichen Problem für die DEC 5.1: ![]() Vor allen Dingen die letzten Einträge dazu sind interessant. Bist Du denn sicher, daß Du in beiden Sprachen den gleichen Initialisierungsvektor verwendest? Gruß Assertor |
Re: Delphi <-> PHP Encryption / Decryption
OK, D2009 ist zwar Unicode, aber sicher daß du deswegen gleich auf Unicode umstellen mußt/kannst?
> AnsiString außerdem sind inhaltsmäßig String und WideString in D2009 auch das Selbe. (wenn ich mir das Ganze überladen da oben so anseh) PS: für C gibt es das [c]-Tag und für PHP kannst du [code] verwenden (siehe Quellcodes im Beitragseditor) |
Re: Delphi <-> PHP Encryption / Decryption
Ich hatte erst einen IV für CBC mit "abcdefghijklmopq" (16 Zeichen). Da ging es ja auch. Nur nach Umstieg auf RAD 2009 geht da nichts mehr...
Wenn ich das richtig sehe, kann ich also von String auf AnsiString wechseln bei meinen Encrypt/Decrypt Version für DCPCrypt? Oder kann ich gleich DEC 5.2 verwenden welches bereits lauffähig ist. Problem ist dort das CBC mit einen Random-IV initialisiert wird und dann noch via Hash verschlüsselt wird. Ich benötige entweder CBC mit definierten IV ohen Hash oder EBC ohne IV und ohne Hash. |
Re: Delphi <-> PHP Encryption / Decryption
Zitat:
|
Re: Delphi <-> PHP Encryption / Decryption
Hi,
nochmal als kleine Hilfe: ![]() ![]() ![]() ![]() Diese Threads behandeln alle im weitesten Sinne das Thema PHP <> Delphi Verschlüsselung. Grundsätzlich sind folgende Fallstricke zu beachten: - Welcher Hash und Cipher wird verwendet? (hier bereits bekannt) - Welcher Initialisierungsvektor wird genutzt? - Wird ein Salt verwendet? - Ist ein Padding nötig und welches wird verwendet? - Welches Format haben die Eingabe- und Ausgabedaten Ich sehe in Deinem PHP code keinerlei Salt. Also muß der beim DEC auch raus, sonst kann das nicht gehen. Dann solltest Du entsprechend der anderen Threads den IV für PHP und Delphi festlegen, damit hier eine gleiche Basis vorliegt. Die Formatierung in Base64/Mime64 ist ja auch bereits gelöst. Der letzte Fallstrick ist Unicode. Hier kommt es auch auf den Webserver und dessen Einstellungen an. Du könntest von UTF8 kodierten Daten ausgehen und dann in Delphi 2009 mit UTF8Strings respektive AnsiStrings arbeiten und die Konversion manuell sicherstellen. Damit sollten sich "beide Welten" problemlos verbinden lassen - auch wenn mit etwas Aufwand. Darf ich fragen, wofür dieser Code verwendet werden soll? Wir hatten hier oft genug irgendwelche Windows-Passwort-Entschlüsselungsversuche und irgendwelche Download-Containerformate. Diesem will ich nicht Vorschub leisten, daher wäre ein konkreter Hintergrund etwas mehr Antrieb für die Mühe. Gruß Assertor |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz