当前位置: 首页 > 知识库问答 >
问题:

php mCrypt和Delphi组件之间的AES加密差异

澹台志诚
2023-03-14

我使用的是一个来自chillkat的Delphi组件,它为我做AES加密。它就像一个魅力,服务器接受我的加密请求。所以我尝试使用mcrypt创建一个php挂件。但与Delphi Chillcat结果相比,PHP mcypt结果是不同的,即使所有参数都相同。因此,服务器拒绝php请求。

所有加密设置都是相同的:

    < li >密码名称:AES 128 < li >密码模式:ECB < li >填充方案:用NULL填充 < li >密钥长度:128 < li >键:1234567890 Abe 1234567890 Abe 1234 db < li >要加密的字符串:这是一个非常酷的测试字符串

这是小 php 脚本:

<?php 
    $key = '1234567890ABE1234567890ABE1234DB';
    function string_encrypt($string, $key) {
        $crypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_ECB);
        return $crypted_text;
    }

    function string_decrypt($encrypted_string, $key) {
        $decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted_string, MCRYPT_MODE_ECB);
        return trim($decrypted_text);
    }

    echo $test_str = 'This is a really cool teststring';   echo '<br />';
    $enc_str = string_encrypt($test_str, $key);
    echo bin2hex($enc_str);                                     echo '<br />';
    echo string_decrypt($enc_str, $key);                        echo '<br />';

    ?>

php输出为:e355fbcd91ada4b835e1b030cc9741759219f59fe441ba62e628eca2e8289eb3

这是德尔福代码:

function encrypt(s:PWideChar;mode,padding:integer;algo,cipher,keylength:string):string;
var
crypt: HCkCrypt2;
success: Boolean;
ivHex: PWideChar;
keyHex: PWideChar;
encStr: PWideChar;
decStr: PWideChar;

begin
crypt := CkCrypt2_Create();

//  AES is also known as Rijndael.
CkCrypt2_putCryptAlgorithm('aes');
// "pki", "aes", "blowfish", "blowfish2", "des", "3des", "rc2", "arc4", "twofish", "pbes1" and "pbes2"

//  CipherMode may be "ecb" or "cbc"
CkCrypt2_putCipherMode(crypt,'ecb');

//  KeyLength may be 128, 192, 256
try
  CkCrypt2_putKeyLength(crypt,128);
Except
  showmessage('The encryption key you have used seems to be invalid');
end;


//  The padding scheme determines the contents of the bytes
//  that are added to pad the result to a multiple of the
//  encryption algorithm's block size.  AES has a block
//  size of 16 bytes, so encrypted output is always
//  a multiple of 16.

{
Possible values are:

0 = RFC 1423 padding scheme: Each padding byte is set to the number of padding bytes.
If the data is already a multiple of algorithm's block size bytes, an extra block is
appended each having a value equal to the block size. (for example, if the algorithm's
block size is 16, then 16 bytes having the value 0x10 are added.). (This is also known as
PKCS5 padding: PKCS #5 padding string consists of a sequence of bytes, each of which
is equal to the total number of padding bytes added. )

1 = FIPS81 (Federal Information Processing Standards 81) where the last byte contains
the number of padding bytes, including itself, and the other padding bytes are set to random values.

2 = Each padding byte is set to a random value. The decryptor must know
how many bytes are in the original unencrypted data.

3 = Pad with NULLs. (If already a multiple of the algorithm's block size,
no padding is added).

4 = Pad with SPACE chars(0x20). (If already a multiple of algorithm's block size, no padding is added).
}
CkCrypt2_putPaddingScheme(crypt,3);

//  EncodingMode specifies the encoding of the output for
//  encryption, and the input for decryption.
//  It may be "hex", "url", "base64", or "quoted-printable".
CkCrypt2_putEncodingMode(crypt,'hex');

//  An initialization vector is required if using CBC mode.
//  ECB mode does not use an IV.
//  The length of the IV is equal to the algorithm's block size.
//  It is NOT equal to the length of the key.
ivHex := '';
CkCrypt2_SetEncodedIV(crypt,ivHex,'hex');

//  The secret key must equal the size of the key.  For
//  256-bit encryption, the binary secret key is 32 bytes.
//  For 128-bit encryption, the binary secret key is 16 bytes.

keyHex := '1234567890ABE1234567890ABE1234DB';
CkCrypt2_SetEncodedKey(crypt,keyHex,'hex');

//  Encrypt a string...
//  The input string is 44 ANSI characters (i.e. 44 bytes), so
//  the output should be 48 bytes (a multiple of 16).
//  Because the output is a hex string, it should
//  be 96 characters long (2 chars per byte).


 //encryption
 if mode = 0 then
 begin
   encStr := CkCrypt2__encryptStringENC(crypt,s);
   result := encStr;
 end
 else
 begin
  result := CkCrypt2__decryptStringENC(crypt,s);
 end;


CkCrypt2_Dispose(crypt);
End;

chillkat Delphi组件的输出是:780 f 849 ab 30690433409 d4fb 7b 3357735296 a6e 76 D3 aa 6 b 6 d6c 769 be 99 f 32041

我认为两个输出应该产生相同的值,因为所有的输入参数都是相等的,对吗?

共有2个答案

殳俊晤
2023-03-14

感谢您的宝贵意见,我能够从服务器上收到一个肯定的答案,其中包含以下4行代码:

$key = pack('H*', "*5DB");
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,$mytxt, MCRYPT_MODE_ECB);
$hex2 = bin2hex($ciphertext);
echo strtoupper($hex2);

然而,我了解到

    < li>ECB不安全 < li>mcrypt老旧且无人维护

我将检查替代方案,并相应地更新我的代码。再次感谢!

云煌
2023-03-14

MCrypt期望密钥是二进制字符串,但您将十六进制编码字符串传递给它。

使用

$key = hex2bin($key);

或者

$key = pack('H*', $key);

这取决于PHP支持。这必须在调用mcrypt_encrypt()之前完成。

安全:

永远不要使用ECB模式。它在语义上不安全。攻击者可以从密文中获得很多信息,而无需解密它们。您至少需要使用带有随机IV的CBC模式。您还应该有密文的身份验证标签。

这个答案给你所有你需要知道的东西。剩下一件事,不要使用MCrypt。这是一个旧的未维护的库。

这个答案也非常有帮助,在这方面,用不同的方式来实现同样的事情。

 类似资料:
  • 我的德尔福应用程序使用 TurboPower 密码箱 3 使用 AES 256 加密纯文本信息。我现在想使用PHP解密这些信息。但是涡轮增压锁盒3有一些互操作性问题。 有关详细信息,请查看LockBox 3作者的帖子: http://lock box . seanbdurkin . id . au/tiki-view _ forum _ thread . PHP?comments_parentId

  • 问题内容: 嗨,我正在尝试弄清楚如何复制在C#中但在Java中完成的文本加密。在C#中,仍然让我感到困惑并且似乎无法找到答案的那部分代码是: 基本上,Java中的这段代码等效于什么? 更新: 使用提供的PasswordDeriveBytes代码(第二个代码段),我能够完美地复制C#代码。谢谢Maarten Bodewes。 但似乎无法使其跨平台运行。基本上设置了解码代码(我在C#3.5中无法更改)

  • 我在写需要加密和解密文件的应用程序。我的问题是解密比加密慢5倍。我已经删除了所有的文件读/写操作,并且只对加密进程进行了基准测试。结果非常令人惊讶: 使用(是javax.crypto.cipher的实例)加密1.5MB字节数组 我很惊讶,因为我知道AES解密和加密是对称的过程,在加密和解密速度上应该没有区别。 我使用密码,密钥为256位。

  • 首先,为我将要发布的代码量道歉。我试图使用Java应用程序中的RSA公钥对Android应用程序中的消息进行加密,然后将密文发送回Java环境进行解密,但在尝试解密时,我总是会遇到以下错误: 密文确实包含正确的字节数(512),因此看到“错误填充”异常会让人困惑。SO上的其他类似帖子建议使用“RSA/ECB/PKCS1Padding”作为算法,但这不起作用。 令人烦恼的是,Android环境中的加

  • 本文向大家介绍DES和AES密码之间的区别,包括了DES和AES密码之间的区别的使用技巧和注意事项,需要的朋友参考一下 众所周知,DES和AES都是对称键块密码的类型,在这种加密方法中,只有一个键(秘钥)用于加密和解密电子信息。通过对称加密进行通信的实体必须交换键,以便可以在解密过程中使用它。现在,根据特性,我们可以区分AES和DES。 以下是DES和AES密码之间的重要区别。 序号 键 DES密

  • 我之所以问这个问题,是因为两天来我读了很多关于crypto AES加密的帖子,就在我以为我得到了它的时候,我意识到我根本没有得到它。 这个帖子是最接近我的问题,我有完全相同的问题,但它没有得到回答: CryptoJS AES加密与JAVA AES解密值不匹配 我得到的是已经加密的字符串(我得到的代码只是为了看看他们是怎么做的),所以修改加密方式不是一个选项。这就是为什么所有类似的问题对我来说都不是