【问题标题】:PHP AES 128 ECB Ciphers and Delphi AES 128 ECBPHP AES 128 ECB 密码和 Delphi AES 128 ECB
【发布时间】:2014-06-21 09:29:26
【问题描述】:

我正在使用 AES 128 ECB 使用密钥作为“KRPTTT101103”的 Delphi 加密“sifrelenecek”字符串,它给了我“FBE4A4405D6C1B54503D9B213E41AE56”,我正在使用 http://aes.online-domain-tools.com/ 检查它是正确的。我正在尝试使用此函数创建与 php 相同的加密;

function sifrele($str, $key){
 $block = mcrypt_get_block_size('rijndael_128', 'ecb');
 $pad = $block - (strlen($str) % $block);
 $str .= str_repeat(chr($pad), $pad);
 return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB)); }

print sifrele("sifrelenecek","KRPTTT101103")

但是 php 给我的结果是“+wL2yf+72thixicjw0duQA==”,我怎样才能在 Delphi 中加密并在 php 或相反的情况下解密?

在网上搜索了很多函数,但没有一个函数结果与Delphi或http://aes.online-domain-tools.com/相同

提前致谢。

【问题讨论】:

  • 看起来您的 Delphi 密码为您提供了加密文本的十六进制表示,而 PHP 密码返回 BASE64 编码表示。
  • @Marko 感谢您的回复,我的想法是一样的,但是在那个网站上,他们是如何得到完全相同的结果的,这就是我想要做的,几乎花了我所有的时间一天,我想不通。
  • 问题是你在 PHP 中使用 base64_encode() 函数。我根本不懂 PHP,但你必须将 mcrypt_encrypt() 返回值编码为十六进制,而不是 base64。 bintohex() 也许。
  • 您可能需要bin2hex(),它会获取 mcrypt_encrypt 吐出的二进制垃圾并将其转换为不太友好的十六进制字符串。
  • 您需要考虑代码并了解您在做什么。一种变体清楚地使用十六进制编码。另一个是base64。它就在您使用的代码中。如果没有真正努力去理解它们,你就不会通过随意尝试事物而得到任何结果。你也在做加密货币。永远不要在缺乏理解的情况下做某事。

标签: php delphi encryption cryptography


【解决方案1】:

您正在混合两种不同形式的填充。这就是造成不匹配的原因。这不仅仅是 Base64/hex 的区别。

你的明文是 12 个字节:“sifrelenecek”,编码为:

[115, 105, 102, 114, 101, 108, 101, 110, 101, 99, 101, 107]

如果你用 ZEROES 填充明文,就像 Delphi 所做的那样,并且正如 mcrypt_encrypt 所记录的那样,那么你正在加密:

[115, 105, 102, 114, 101, 108, 101, 110, 101, 99, 101, 107, 0, 0, 0, 0]

生成的密文是 ++SkQF1sG1RQPZshPkGuVg== 在 Base64 中,当解码为纯字节并以十六进制重新编码时,变为“FBE4A4405D6C1B54503D9B213E41AE56” - 这正是在线工具返回的内容。 p>

但是,如果您使用 PKCS#7 填充 填充纯文本,就像您在上面的 PHP 代码中所做的那样:

$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);

然后这个明文用 FOURS 填充并且你正在加密:

[115, 105, 102, 114, 101, 108, 101, 110, 101, 99, 101, 107, 4, 4, 4, 4]

生成的密文是 +wL2yf+72thixicjw0duQA== -- 正是您在上面的问题中显示的内容。

要么两边都用 ZEROES 填充,要么两边都用 PKCS#7 填充,你的结果应该匹配。

【讨论】:

  • 我过去也遇到过同样的问题,不得不用零填充。那是因为我使用的是默认情况下执行此操作的 DCPCrypt。 OP 没有说明他使用什么 Delphi 代码,因此他的选择可能更广泛。
  • 请注意,如果要加密二进制数据,则应使用 PKCS#7 填充。仅当纯文本不以 00 值字符结尾时,零填充才有效。另请注意,对于大多数用途而言,ECB 并不安全,包括文本加密。
  • @JimFlood :这不是真的 ++SkQF1sG1RQPZshPkGuVg== 不等于 FBE4A4405D6C1B54503D9B213E41AE56 你也在混合 ++SkQF1sG1RQPZshPkGuVg== 十六进制 = 2b2b536b5146317347315251505a7368506b477556673d3
  • @moskito-x:如果您对字符串 '++SkQF1sG1RQPZshPkGuVg==' 进行 Base64 解码,然后对结果字节数组进行十六进制编码,您将得到“FBE4A4405D6C1B54503D9B213E41AE56”。十六进制字符串“2b2b536b5146317347315251505a7368506b477556673d3”是字面意思,十六进制的ASCII字符串“++SkQF1sG1RQPZshPkGuVg==”,即0x2b是'+',0x2b是'+',0x53是'S',等等。'k'表示二进制密文十六进制编码,而不是 Base64 字符串。
  • 所以这放在你的答案中很容易被误解:The resulting ciphertext is ++SkQF1sG1RQPZshPkGuVg== (in Base64) -- just what the online tool returns (i.e. the same value, in hex.)
【解决方案2】:

正如我们所见,您尝试比较一个使用十六进制明确编码的。另一个是base64。

在php中

  • 放开填充物(这是自动完成的)。
  • 不要做 base64_encode(你在 delphi 中也没有做过)。

php手册

说明:


字符串 mcrypt_encrypt ( 字符串 $cipher , 字符串 $key , 字符串 $data , 字符串 $mode [, 字符串 $iv ] )

加密数据并返回。

......

数据

将使用给定密码和模式加密的数据。如果 数据的大小不是n * blocksize,数据会被填充 带有“\0”。

返回的密文可以大于数据的大小 这是数据给出的。

ECB 模式忽略 IV,因此显示同时使用 MCRYPT_MODE_ECB 和 IV 的示例会产生误导(手册中的示例显示相同的内容)。此外,重要的是要知道 ECB 对随机数据很有用,但结构化数据应该使用更强大的模式,如 MCRYPT_MODE_CBC

php代码

function encrypt($input) {
    // $iv = mcrypt_create_iv(32);
    $mcr = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, "KRPTTT101103",
                          $input, MCRYPT_MODE_ECB);
    $hex2 = bin2hex($mcr); // Convert binary data into hexadecimal representation
    return strtoupper($hex2);
    // base64_encode($mcr);
    }

$encryptedhextext = encrypt("sifrelenecek");

 if ($encryptedhextext == "FBE4A4405D6C1B54503D9B213E41AE56" ) {
   echo   "Encrypted Hex text in Delphi and php are equal<br />";    
   echo $encryptedhextext." == FBE4A4405D6C1B54503D9B213E41AE56";
 }

输出

Delphi 和 php 中的加密十六进制文本是相等的
FBE4A4405D6C1B54503D9B213E41AE56 == FBE4A4405D6C1B54503D9B213E41AE56

【讨论】:

  • 感谢您的解释,在我阅读了 cmets 并回答后,我才意识到我比 php 的菜鸟要低得多,在这个项目之后我真的需要在 php 上工作。但是一次有没有机会给我两个函数来解密 delphi 的数据并再次加密,就像 delphi 对 php 所做的那样?对不起,我被困住了,我真的很绝望。
猜你喜欢
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
相关资源
最近更新 更多