• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

使用dcpcrypt在delphi和php:间同步加密

用户头像
it1352
帮助1

问题说明

我使用的是Delphi 2009,我在这里看到的大多数答案是2010
我正在尝试将加密(delphi)同步到解密(php)并失败。

I'm using Delphi 2009 and most of the answers I've seen here are for 2010 I am trying to sync encryption (delphi) to decryption (php) and failing.

在delphi中生成加密的字符串:

generate the encrypted string in 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";
?>

正确答案

#1

几个问题,我想: >

Several issues, I think :-)

  • des.InitStr()从8个空字节内部创建一个IV,然后对其进行加密。您需要在PHP中使用相同的IV。

  • des.InitStr() internally creates an IV from 8 null bytes which it then encrypts. You need to use the same IV in your PHP.

sha1($ key)生成十六进制字符串,而不是密码的实际字节数。您需要像mhash这样的东西。

The sha1($key) produces a hex string rather than the actual bytes of the password. You need something like mhash instead.

我无法使用给定的Delphi功能重新设计$ enc字符串。

I couldn't manage to reproduce your $enc string with the given Delphi function.

Unicode问题 - 密码和源文本将被视为Delphi中的unicode。

Unicode issues - the password and source text are going to be treated as unicode in Delphi.

你似乎是基础64在Delphi例程中编码源两次。 des.EncryptString和des.DecryptString产生和使用基本的64编码字符串,所以不需要再次执行。

You seem to be base 64 encoding the source twice in the Delphi routines. des.EncryptString and des.DecryptString produce and consume base 64 encoded strings so no need to do it again.

填充

根据我以前的答案此处 - 这是我的建议:

Based on my previous answer here - this is my suggestion:

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";
?>

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /reply/detail/tanhcfjaia
系列文章
更多 icon
同类精品
更多 icon
继续加载