首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP AES 128 ECB密码和Delphi AES 128 ECB

PHP AES 128 ECB密码和Delphi AES 128 ECB
EN

Stack Overflow用户
提问于 2014-06-20 14:53:56
回答 2查看 3.8K关注 0票数 0

我用Delphi加密"sifrelenecek“字符串,使用AES 128欧洲央行使用密钥作为"KRPTTT101103”,它给我"FBE4A4405D6C1B54503D9B213E41AE56",我正在检查http://aes.online-domain-tools.com/,它是正确的。我试图使用这个函数用php创建相同的加密;

代码语言:javascript
复制
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中解密?

在网上搜索,发现有这么多的函数,但没有任何一个函数的结果与德尔福或http://aes.online-domain-tools.com/相同。

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-20 18:49:13

正如我们所看到的,您可以尝试比较使用十六进制清晰编码的一个。另一个用base64。

in php

  • 让衬垫离开(这是自动完成的)。
  • 不要做base64_encode (您在德尔菲中也没有这样做)。

php手册

描述:

字符串mcrypt_encrypt ( string $cipher,string $key,string $data,string $mode,string $iv ) 加密数据并返回数据。 . 数据 将用给定的密码和模式加密的数据。如果数据的大小不是n*块大小,数据将被填充'\0‘。 返回的密码文本可以大于由数据提供的数据的大小。

欧洲央行模式忽略了IV,因此使用MCRYPT_MODE_ECB和IV (手册中的示例显示相同的内容)显示示例是有误导性的。另外,重要的是要知道欧洲央行对于随机数据是有用的,但是结构化数据应该使用更强的模式,比如MCRYPT_MODE_CBC

php代码

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 2014-06-20 19:41:02

你在混合两种不同形式的填充物。这就是造成这种错配的原因。这不仅仅是一个基数64/十六进制的差异。

明文为12个字节:"sifrelenecek",编码为:

代码语言:javascript
复制
[115, 105, 102, 114, 101, 108, 101, 110, 101, 99, 101, 107]

如果您使用填充明文,就像德尔福所做的那样,而mcrypt_encrypt被记录为正在做的事情,那么您就是在加密:

代码语言:javascript
复制
[115, 105, 102, 114, 101, 108, 101, 110, 101, 99, 101, 107, 0, 0, 0, 0]

由此产生的密文是++SkQF1sG1RQPZshPkGuVg== in Base64,当解码为普通字节并以十六进制重新编码时,它变成了"FBE4A4405D6C1B54503D9B213E41AE56“--这正是在线工具返回的内容。

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

代码语言:javascript
复制
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);

然后,这个明文用四层填充,而您正在加密:

代码语言:javascript
复制
[115, 105, 102, 114, 101, 108, 101, 110, 101, 99, 101, 107, 4, 4, 4, 4]

由此产生的密文是+wL2yf+72thixicjw0duQA== --这正是你在问题中所显示的。

无论是在两边放置零,还是在两边使用PKCS#7,结果都应该是一致的。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24330135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档