2013-08-08 4 views
0

Я шифрую некоторые данные в Delphi и отправляю их через GET в PHP-скрипт, который расшифровывает его и добавляет результат в базу данных MySQL. Проблема в том, что иногда она добавляет один « » или « » в конце данных. Вот код:AES crypt Delphi/PHP поврежденный вывод

const 
    URL = 'http://127.0.0.1/script.php?data='; 
    PACK_SEPARATOR = '|'; 
    KeySize = 32; 
    BlockSize = 16; 

function aes_encrypt(const Data: string; const Key: string; const IV: string) : string; 
var 
    Cipher : TDCP_rijndael; 
    tempData, tempKey, tempIV : string; 
begin 
    tempKey := PadWithZeros(Key,KeySize); 
    tempIV := PadWithZeros(IV,BlockSize); 
    tempData := PadWithZeros(Data,BlockSize); 
    Cipher := TDCP_rijndael.Create(nil); 
    if Length(Key) <= 16 then 
    Cipher.Init(tempKey[1],128,@tempIV[1]) 
    else if Length(Key) <= 24 then 
    Cipher.Init(tempKey[1],192,@tempIV[1]) 
    else 
    Cipher.Init(tempKey[1],256,@tempIV[1]); 
    Cipher.EncryptCBC(tempData[1],tempData[1],Length(tempData)); 
    Cipher.Free; 
    FillChar(tempKey[1],Length(tempKey),0); 
    Result := Base64EncodeStr(tempData); 
end; 


function PadWithZeros(const str : string; size : integer) : string; 
var 
    origsize, i : integer; 
begin 
    Result := str; 
    origsize := Length(Result); 
    if ((origsize mod size) <> 0) or (origsize = 0) then 
    begin 
    SetLength(Result,((origsize div size)+1)*size); 
    for i := origsize+1 to Length(Result) do 
     Result[i] := #0; 
    end; 
end; 

function HTTPEncode(const AStr: String): String; 
const 
    NoConversion = ['A'..'Z','a'..'z','*','@','.','_','-']; 
var 
    Sp, Rp: PChar; 
begin 
    SetLength(Result, Length(AStr) * 3); 
    Sp := PChar(AStr); 
    Rp := PChar(Result); 
    while Sp^ <> #0 do 
    begin 
    if Sp^ in NoConversion then 
     Rp^ := Sp^ 
    else 
     if Sp^ = ' ' then 
     Rp^ := '+' 
     else 
     begin 
     FormatBuf(Rp^, 3, '%%%.2x', 6, [Ord(Sp^)]); 
     Inc(Rp,2); 
     end; 
    Inc(Rp); 
    Inc(Sp); 
    end; 
    SetLength(Result, Rp - PChar(Result)); 
end; 


packedData := Memo1.Lines.Text + PACK_SEPARATOR + Edit1.Text + PACK_SEPARATOR + Edit2.Text; 
encryptedData := aes_encrypt(packedData, KEY, IV); 
encryptedData := HTTPEncode(encryptedData); 
serverMsg := DownloadFile(URL+encryptedData); 

длина «packedData» перед шифрованием около 133. После шифрования около 200, так что не сломать некоторые серверы GET ограничение данных.

Теперь PHP код:

function aes_decrypt($dataToDecrypt, $key, $iv) 
{ 
    $decoded = base64_decode($dataToDecrypt); 
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $decoded, MCRYPT_MODE_CBC, $iv); 
    return $decrypted; 
} 

$packedData = aes_decrypt($_GET['data'], KEY, IV); 
$unpacked = explode(PACK_SEPARATOR, $packedData); 
$smth1 = $unpacked[0]; 
$smth2 = $unpacked[1]; 
$smth3 = $unpacked[2]; 
$params = array(':thing' => $somevar, ':data1' => $smth1, ':data2' => $smth2, ':data3' => $smth3); 
$query = $pdo->prepare('UPDATE one_table SET somedata1 = :data1 , somedata2 = :data2 , somedata3 = :data3 WHERE something = :thing LIMIT 1'); 
$success = $query->execute($params); 

Я провожу очень много времени, пытаясь решить эту проблему. Некоторое время назад у меня были проблемы с зашифрованным выходом PHP с двоичными данными, проблема была в функции aes_decrypt, поэтому я изменил ее, вы можете видеть выше. Прямо сейчас я не знаю, где проблема. Дельфы шифруют, расшифровывают PHP или отправляют данные через GET? Спасибо за любую помощь, которую вы можете предоставить.

ответ

1

Похож на проблему с кодировкой с различными наборами символов. Проверьте наборы символов, которые вы используете в delphi и php. Я могу представить, что ваши строки являются латинскими-1 в delphi и UTF-8 в php. И из-за этого появляются странные символы.

+0

Я преобразовал с помощью файла Notepad ++ PHP в ANSI, и он исправил другую ошибку с получением странных сообщений из PHP-скрипта. Однако в поле MySQL все еще были странные символы « ». Я попытался изменить кодировку поля с utf8_general_ci на latin1_general_ci, и это не сработало, все же появились странные символы. Я исправил его: $ smth3 = trim ($ smth3); Возможно, это не лучшее решение, но оно отлично работает до тех пор, пока im не сохранит простые значения в базе данных. Благодарю. – Fox

+0

, тогда это были некоторые странные закодированные пробелы. ;) Сложно, вам нужно извлечь кодовые последовательности этих символов. Но приятно, что это работает для вас –

0

Это мой Delphi XE3 и PHP код:

Delphi XE3 код:

uses IdHash, IdCoderMIME, IdHashMessageDigest, 
    DCPrijndael, DCPbase64; 

function xBase64Encode(const Input: string): AnsiString; 
    begin 
     result := TIdEncoderMIME.EncodeString(Input, TEncoding.UTF8); 
    end; 

    function xBase64Decode(const Input: AnsiString): string; 
    begin 
     result := TIdDecoderMIME.DecodeString(Input, TEncoding.UTF8); 
    end; 

    function PadWithZeros(const str: AnsiString; size: integer): AnsiString; 
    var 
     origsize, i: integer; 
    begin 
     Result := str; 
     origsize := Length(Result); 
     if ((origsize mod size) <> 0) or (origsize = 0) then 
     begin 
     SetLength(Result, ((origsize div size) + 1) * size); 
     for i := origsize + 1 to Length(Result) do 
      Result[i] := #0; 
     end; 
    end; 

    function AES_Rijndael_Encript(xData, xKey, xIV: string): string; 
     var 
      Cipher: TDCP_rijndael; 
      B64, Data, Key, IV: AnsiString; 
     begin 
      B64 := xBase64Encode(xData); 
      // Pad Key, IV and Data with zeros as appropriate 
      Key := PadWithZeros(AnsiString(xKey), KeySize); 
      IV := PadWithZeros(AnsiString(xIV), BlockSize); 
      Data := PadWithZeros(B64, BlockSize); 
      // Create the cipher and initialise according to the key length 
      Cipher := TDCP_rijndael.Create(nil); 
      if Length(AnsiString(xKey)) <= 16 then 
      Cipher.Init(Key[1], 128, @IV[1]) 
      else if Length(AnsiString(xKey)) <= 24 then 
      Cipher.Init(Key[1], 192, @IV[1]) 
      else 
      Cipher.Init(Key[1], 256, @IV[1]); 
      // Encrypt the data 
      Cipher.EncryptCBC(Data[1], Data[1], Length(Data)); 
      // Free the cipher and clear sensitive information 
      Cipher.Free; 
      FillChar(Key[1], Length(Key), 0); 
      // Display the Base64 encoded result 
      Result := Base64EncodeStr(Data); 
     end; 

     function AES_Rijndael_Decript(xData, xKey, xIV: string): string; 
     var 
      Cipher : TDCP_rijndael; 
      Data, Key, IV : ansistring; 
      xResult : string; 
     begin 
      // Pad Key and IV with zeros as appropriate 
      Key := PadWithZeros(ansistring(xKey),KeySize); 
      IV := PadWithZeros(ansistring(xIV),BlockSize); 
      // Decode the Base64 encoded string 
      Data := Base64DecodeStr(ansistring(xData)); 
      // Create the cipher and initialise according to the key length 
      Cipher := TDCP_rijndael.Create(nil); 
      if Length(ansistring(xKey)) <= 16 then 
      Cipher.Init(Key[1],128,@IV[1]) 
      else if Length(ansistring(xKey)) <= 24 then 
      Cipher.Init(Key[1],192,@IV[1]) 
      else 
      Cipher.Init(Key[1],256,@IV[1]); 
      // Decrypt the data 
      Cipher.DecryptCBC(Data[1],Data[1],Length(Data)); 
      // Free the cipher and clear sensitive information 
      Cipher.Free; 
      FillChar(Key[1],Length(Key),0); 
      // Display the result 
      Result := Data; 
      xResult := Trim(Data); 
      Result := xBase64Decode(xResult); 
     end; 

Как функции пользователя:

boxKey.Text := 'gmAetc4EydWJg2TcnH34'; 
boxIV.Text := 'AHsq3SCN7usJzqLi'; 

Memo2.Lines.Text := AES_Rijndael_Encript(Memo1.Lines.Text, boxKey.Text, boxIV.Text); 
Memo1.Lines.Text := AES_Rijndael_Decript(Memo2.Lines.Text, boxKey.Text, boxIV.Text); 

PHP код:

public function AES_Rijndael_Decript($data) { 
     $key = 'gmAetc4EydWJg2TcnH34'; 
     $iv = 'AHsq3SCN7usJzqLi'; 
     return base64_decode(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($data), MCRYPT_MODE_CBC, $iv)); 
    } 
    public function AES_Rijndael_Encript($data) { 
     $key = 'gmAetc4EydWJg2TcnH34'; 
     $iv = 'AHsq3SCN7usJzqLi'; 
     return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$key,base64_encode($data),MCRYPT_MODE_CBC,$iv));   
    } 
Смежные вопросы