как синхронизировать шифрование между delphi и php, используя dcpcrypt

Я использую Delphi 2009, и большинство ответов, которые я здесь видел, относятся к 2010 году. Я пытаюсь синхронизировать шифрование (delphi) с расшифровкой (php) и неудачей.

генерировать зашифрованную строку в delphi:

program Project4; {$APPTYPE CONSOLE} uses SysUtils, DCPcrypt2, DCPsha1, DCPblockciphers, DCPdes, EncdDecd; var des: tdcp_des; enc,dec: ansistring; begin try des:=tdcp_des.Create(nil); des.InitStr('test', tdcp_sha1); enc:=encodestring(des.EncryptString('this is a test')); des.Free; des:=tdcp_des.Create(nil); des.InitStr('test', tdcp_sha1); dec:=des.DecryptString(decodestring(enc)); des.Free; writeln(enc); writeln(dec); except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end. 

расшифровать в php:

 <?php function decrypt($str, $key) { $size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_CBC); $iv = mcrypt_create_iv($size, MCRYPT_DEV_RANDOM); $data = base64_decode($str); $block = mcrypt_get_block_size('des', 'ecb'); $k = substr(sha1($key), 0, $block); $str = mcrypt_decrypt(MCRYPT_DES, $k, $data, MCRYPT_MODE_CBC, $iv); $pad = ord($str[($len = strlen($str)) - 1]); return substr($str, 0, strlen($str) - $pad); } $enc = 'TW5mbVFhODUyR2FoOTA2WWJIOD0='; $dec = decrypt($enc, 'test'); echo "$dec\n"; ?> 

Несколько вопросов, я думаю 🙂

  • des.InitStr () внутренне создает IV из 8 нулевых байтов, которые затем шифрует. Вы должны использовать тот же IV в своем PHP.

  • Sha1 ($ key) создает шестнадцатеричную строку, а не фактические байты пароля. Вместо этого вам нужно что-то вроде mhash.

  • Я не смог воспроизвести строку $ enc с данной функцией Delphi.

  • Проблемы с Unicode – пароль и исходный текст будут обрабатываться как unicode в Delphi.

  • Кажется, вы являетесь базой 64, кодирующей источник дважды в подпрограммах Delphi. des.EncryptString и des.DecryptString производят и потребляют базовые 64 кодированные строки, поэтому не нужно делать это снова.

  • набивка

Основываясь на моем предыдущем ответе здесь – это мое предложение:

 function EncryptStringDES: string; var des: TDCP_des; src, enc, b64: TBytes; index, slen, bsize, padsize: integer; begin des:=tdcp_des.Create(nil); try des.InitStr(AnsiString('test'), tdcp_sha1); src := TEncoding.UTF8.GetBytes('this is a test'); slen := Length(src); // Add padding bsize := des.BlockSize div 8; padsize := bsize - (slen mod bsize); Inc(slen, padsize); SetLength(src, slen); for index := padsize downto 1 do begin src[slen - index] := padsize; end; SetLength(enc, slen); des.EncryptCBC(src[0], enc[0], slen); result := EncdDecd.EncodeBase64(@enc[0], Length(enc)); finally des.Free; end; end; function DecryptStringDES(ASource: string): string; var des: TDCP_des; key, src, dec, b64: TBytes; pad, slen: integer; begin des := TDCP_des.Create(nil); try des.InitStr(AnsiString('test'), tdcp_sha1); src := EncdDecd.DecodeBase64(AnsiString(ASource)); slen := Length(src); SetLength(dec, slen); des.DecryptCBC(src[0], dec[0], slen); // Remove padding pad := dec[slen - 1]; SetLength(dec, slen - pad); result := TEncoding.UTF8.GetString(dec); finally des.Free; end; end; 

и PHP:

 <?php function decrypt_SO($str, $key) { //$ivsize = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_CBC); //$blocksize = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC); $keysize = mcrypt_get_key_size(MCRYPT_DES, MCRYPT_MODE_CBC); // Need to use the SAME IV as the Delphi function. By default // this is (0,0,0,0,0,0,0,0) encrypted using ECB mode and gives the // following bytes: $ivbytes = array(72, 163, 99, 62, 219, 111, 163, 114); $iv = implode(array_map("chr", $ivbytes)); $enc = base64_decode($str); $k = mhash(MHASH_SHA1, $key); $dec = mcrypt_decrypt(MCRYPT_DES, substr($k, 0, $keysize), $enc, MCRYPT_MODE_CBC, $iv); $pad = ord($dec[strlen($dec) - 1]); return substr($dec, 0, strlen($dec) - $pad); } $enc = 'WRaG/8xlxqqcTAJ5UAk4DA=='; $dec = decrypt_SO($enc, 'test'); echo "$dec\n"; ?> 

я использую такую ​​интеграцию с успехом, но я не могу предоставить больше информации, чем это, она принадлежит моему работодателю.

вы инициализировали mycrypt?

 $iv = "nononono"; $key = "nononono"; $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); mcrypt_generic_init($td, $key, $iv); $decoded = base64_decode($mySecretString); $decryptedcbc = mdecrypt_generic($td, $decoded); mcrypt_generic_deinit($td); 

Не забудьте правильно закодировать свою строку в delphi, я использую Base64EncodeStr (Buffer);

Я надеюсь, что это помогает.

кто является iv байтами

 $ivbytes = array(72, 163, 99, 62, 219, 111, 163, 114); 

для ключа: test123456

 $ivbytes = array(??, ??, ??, ??, ??, ??, ??, ??);