【问题标题】:different Delphi / PHP Encryption-Decryption using Rijndael使用 Rijndael 进行不同的 Delphi / PHP 加密-解密
【发布时间】:2015-02-09 15:13:48
【问题描述】:

我正在尝试使用 Rijndael 从 php 到 Delphi 加密/解密字符串。

如果我从 Delphi 解密一个 PHP 字符串 ... 工作正常。

如果我用 Delphi 加密一个字符串,结果字符串没问题,但更短

为了测试,我使用了一个 62 个字符的字符串。用delphi加密的字符串比PHP少了4个字符

这些字符串...最后一个字符:

PHP:GyLWj1anBJRmE8mBsaO5cvTrcbvvA==

德尔福:GyLWj1anBJRmE8mBsaO5cvTrcbv

感谢您的建议

我使用这个源代码示例:

PHP:

function encrypt ($key, $value)
{
  $padSize = 16 - (strlen ($value) % 16) ;
  $value = $value . str_repeat (chr ($padSize), $padSize) ;
  $output = mcrypt_encrypt (MCRYPT_RIJNDAEL_128, $key, $value, MCRYPT_MODE_CBC, 'xxxxxxx') ;
  return base64_encode ($output) ;
}

德尔福加密:

function EncryptData3(Data: string; AKey: AnsiString; AIv: AnsiString): string;
var
  cipher: TDCP_rijndael;
  key, iv, src, dest, b64: TBytes;
  index, slen, bsize, pad: integer;
begin
  //key := Base64DecodeBytes(TEncoding.UTF8.GetBytes(AKey));
  //iv := Base64DecodeBytes(TEncoding.UTF8.GetBytes(AIv));
  key := TEncoding.ASCII.GetBytes(AKey);
  iv := TEncoding.ASCII.GetBytes(AIv);

  src := TEncoding.ascii.GetBytes(Data);

  cipher := TDCP_rijndael.Create(nil);
  try
    cipher.CipherMode := cmCBC;
    // Add padding.
    // Resize the Value array to make it a multiple of the block length.
    // If it's already an exact multiple then add a full block of padding.
    slen := Length(src);
    bsize := (cipher.BlockSize div 8);
    pad := bsize - (slen mod bsize);
    Inc(slen, pad);
    SetLength(src, slen);

    for index := pad downto 1 do
    begin
      src[slen - index] := pad;
    end;

    SetLength(dest, slen);
    cipher.Init(key[0], 256, @iv[0]); // DCP uses key size in BITS not BYTES
    cipher.Encrypt(src[0], dest[0], slen);

    b64 := Base64EncodeBytes(dest);
    result := TEncoding.Default.GetString(b64);
  finally
    cipher.Free;
  end;
end;

Delphi 解密...不起作用:

function DecryptData3(Data: string; AKey: AnsiString; AIv: AnsiString): string;
var
  key, iv, src, dest: TBytes;
  cipher: TDCP_rijndael;
  slen, pad: integer;
begin
  //key := Base64DecodeBytes(TEncoding.UTF8.GetBytes(AKey));
  //iv := Base64DecodeBytes(TEncoding.UTF8.GetBytes(AIv));
  key := TEncoding.ASCII.GetBytes(AKey);
  iv := TEncoding.ASCII.GetBytes(AIv);

  src := Base64DecodeBytes(TEncoding.UTF8.GetBytes(Data));

  cipher := TDCP_rijndael.Create(nil);
  try
    cipher.CipherMode := cmCBC;
    slen := Length(src);
    SetLength(dest, slen);
    cipher.Init(key[0], 256, @iv[0]); // DCP uses key size in BITS not BYTES
    cipher.Decrypt(src[0], dest[0], slen);
    // Remove the padding. Get the numerical value of the last byte and remove
    // that number of bytes
    pad := dest[slen - 1];
    SetLength(dest, slen - pad);

    // Base64 encode it
    result := TEncoding.Default.GetString(dest);
  finally
    cipher.Free;
  end;
end;

【问题讨论】:

  • 如果想阅读整个 WWW 中与 this 相关的所有问题/答案或博客文章,您可以花几年时间阅读。在这里,这个问题几乎每周都会在 delphi 角落问一次。
  • 我找到了问题的两个答案......但它没有解决任何问题。
  • 肯,链接的答案没有有一个可接受的答案。
  • 要清楚,vA== 表示单个字节。因此,两个加密文本之间存在一个字节的差异。你显然很接近。我会试着找出那一字节的区别是什么。

标签: php delphi encryption cryptography rijndael


【解决方案1】:

我不知道我是否使用了正确的方法...但是如果我将字节值转换为字符串并在此链接中使用此 Base64Encode:

Simple code to encrypt an .INI file string using a password

现在我正确加密了。这是一个例子:

SetString(stringValue, PAnsiChar(@dest[0]), slen); 
result := Base64Encode2(stringValue);

【讨论】:

  • Delphi 程序员什么时候才能知道文本和二进制是不一样的。该二进制文件不属于字符串。而那个 base64 将二进制编码为文本。
猜你喜欢
  • 2011-10-26
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 1970-01-01
相关资源
最近更新 更多