0

I am trying to do encryption and decryption between PHP and Delphi.

My PHP code is;

<?php
error_reporting(E_ALL);
$key = "5y';syhl0ngl4st1ngdfvt5tt";

function decrypt1($string, $key){

    $y = 1;
    for ($x = 1;$i < strlen($string); $i++) {
        $a = (ord($string[$x]) and 0x0f) ^ (ord($key[$y]) and 0x0f);
        $string[$x] = chr((ord($string[$x]) and 0xf0) + $a);

        $y++;
        if ($y > strlen($key)) $y = 1;
    }
    return $string;
}

echo decrypt1(base64_decode("cWx0fw=="),$key);
?>

My Delphi is;

function Decrypt1(Str : String; Key: string): AnsiString;
var
  X, Y : Integer;
  A : Byte;
begin
  Y := 1;
  for X := 1 to Length(Str) do
  begin
    A := (ord(Str[X]) and $0f) xor (ord(Key[Y]) and $0f);
    Str[X] := char((ord(Str[X]) and $f0) + A);

    Inc(Y);
    If Y > length(Key) then Y := 1;
  end;
  Result := Str;
end;

function Encrypt(Str : String; Key: string): String;
begin
result:= Decrypt1(str,key);
result:= EncodeBase64(result);
end;

The encryption / decryption doesn't work. When attempting to decode encoded value from Delphi in PHP, I get a load of rubbish.

I have a feeling it might be something to do with the character encoding?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Jake Evans
  • 978
  • 5
  • 13
  • 33
  • Delphi works with Ansi or since D2009 with UTF16 and PHP with UTF8. You have to ensure to work on the same encoding. – Sir Rufo Aug 18 '14 at 22:46
  • 3
    Step 1 is to stop using strings to hold byte arrays. Use `TBytes`. This is the single biggest misapprehension that we encounter regarding encryption. Encryption operates on binary data and not text. – David Heffernan Aug 19 '14 at 05:43

2 Answers2

4

There are a few problems here:

  • String indexing in PHP is zero-based and not one-based as your code assumes.
  • Delphi strings (well, in modern Delphi) are UTF-16 encoded. Your code assumes some unspecified 8 bit encoding.
  • Encryption/decryption operates on binary data rather than text and you fail to recognise this.

You should encrypt like this:

  1. Encode the text in a specific, well-defined encoding. For instance, UTF-8. This gives a byte array. In Delphi that is TBytes.
  2. Encrypt this byte array to yield another byte array.
  3. Encode that byte array using base64 to get a text representation.

Decryption simply reverses these steps. The key thing to absorb is that encryption/decryption operates on binary data rather than text.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

I'm going to take a guess here and say you're using a Delphi version where string is a UnicodeString. PHP generally uses some ANSI encoding, which can be configured. The best way to deal with this is to have your Delphi code save to UTF-8 and load from UTF-8, and make sure your PHP loads from UTF-8. Standardize on one encoding across the board and then issues like this won't happen.

Community
  • 1
  • 1
Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • I'm actually using Delphi XE6, so I would assume it's Ansi? – Jake Evans Aug 18 '14 at 22:49
  • 1
    @Tom: Anything D2009 or later (including the entire XE line) is Unicode. – Mason Wheeler Aug 18 '14 at 22:52
  • So how would I make Delphi and PHP encoding's compatible? – Jake Evans Aug 18 '14 at 23:39
  • @Tom: By doing exactly what I said. Use a standard encoding. When you're writing data out, use a `UTF8String` instead of a **string**, for example. – Mason Wheeler Aug 19 '14 at 00:03
  • I've tried that, I am still getting a different result when doing it in PHP – Jake Evans Aug 19 '14 at 00:08
  • @Tom: Oh, and make sure you use `UTF8String` and `AnsiChar` rather than `String` and `Char` for your encrypt and decrypt functions. – Mason Wheeler Aug 19 '14 at 00:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/59550/discussion-between-tom-sothcott-and-mason-wheeler). – Jake Evans Aug 19 '14 at 00:24
  • Advice to use UTF-8 is incomplete. One might advise to get UTF-8 encoded bytes and then encrypt that to encrypted bytes. But at that point you have binary data that cannot be treated as text. Perhaps one might base64 encode as text. But there's so much more here than a blanket suggestion to standardise on UTF-8. – David Heffernan Aug 19 '14 at 08:51