如何使用dcpcrypt在delphi和php之间同步加密

前端之家收集整理的这篇文章主要介绍了如何使用dcpcrypt在delphi和php之间同步加密前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用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),$block);
    $str = mcrypt_decrypt(MCRYPT_DES,$k,$data,MCRYPT_MODE_CBC,$iv);
    $pad = ord($str[($len = strlen($str)) - 1]);
    return substr($str,strlen($str) - $pad);
}

$enc = 'TW5mbVFhODUyR2FoOTA2WWJIOD0=';
$dec = decrypt($enc,'test');
echo "$dec\n";
?>

解决方法

我认为有几个问题:-)

> des.InitStr()在内部从8个空字节创建一个IV然后加密.您需要在PHP中使用相同的IV.
> sha1($key)生成十六进制字符串而不是密码的实际字节.你需要像mhash这样的东西.
>我无法使用给定的Delphi函数重现您的$enc字符串.
> Unicode问题 – 在Delphi中,密码和源文本将被视为unicode.
>您似乎是在Delphi例程中对源进行两次编码. des.EncryptString和des.DecryptString生成并使用base 64编码的字符串,因此无需再次执行.
>填充

基于我以前的答案here – 这是我的建议:

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) encrypted using ECB mode and gives the
    // following bytes:
    $ivbytes = array(72,163,99,62,219,111,114);
    $iv = implode(array_map("chr",$ivbytes));

    $enc = base64_decode($str);
    $k = mhash(MHASH_SHA1,$key);
    $dec = mcrypt_decrypt(MCRYPT_DES,substr($k,$keysize),$enc,$iv);

    $pad = ord($dec[strlen($dec) - 1]);
    return substr($dec,strlen($dec) - $pad);
}

$enc = 'WRaG/8xlxqqcTAJ5UAk4DA==';
$dec = decrypt_SO($enc,'test');
echo "$dec\n";
?>

猜你在找的Delphi相关文章