PHP openssl_decrypt与在线工具没有得到相同的结果

问题描述 投票:1回答:1

使用在线加密/解密工具,使用DES-ECB,我可以使用8位十六进制密钥对8位十六进制数字进行加密,从而得到8位十六进制结果。我可以使用相同的密钥解密该8位数字的结果,并获得我加密的原始数据。

但是,我无法使用PHP在本地复制它。事实证明,我在线获得的加密结果是实际产生的16位数字中的前8位。没问题...但是当我尝试使用PHP在本地解密时,我需要全部16位数字才能获取原始数据。

我该如何仅使用8位数字解密并仍然像在线工具一样获得原始数据?

在线结果:

正在加密:

$data = '03 67 A6 7F C2 00 0A DB';
$key = '00 F2 83 CD BA 41 6F FF';
$result = '8b be 0f 3b ae 92 56 07';

验证:http://des.online-domain-tools.com/link/1b40d6agZYE0TFR5sM/

解密:

$data = '8b be 0f 3b ae 92 56 07';
$key = '00 F2 83 CD BA 41 6F FF';
$result = '03 67 A6 7F C2 00 0A DB';

验证:http://des.online-domain-tools.com/link/1b40e05gD5TNgMb72h/

本地PHP测试:

$enc = openssl_encrypt( hex2bin('0367A67FC2000ADB'), 'DES-ECB', hex2bin('00F283CDBA416FFF'), 1);

[bin2hex($enc)产生8bbe0f3bae9256071da486ee680f8449

如果仅解密前8个十六进制数字,则不会获得与使用在线工具相同的结果:

$dec = openssl_decrypt( hex2bin('8bbe0f3bae925607'), 'DES-ECB', hex2bin('00F283CDBA416FFF'), 1);

[bin2hex($dec)结果为null(如果我们不转换为十六进制,则为false)

但是,如果我输入完整的16位十六进制作为加密数据,则会得到正确的结果:

$dec = openssl_decrypt( hex2bin('8bbe0f3bae9256071da486ee680f8449'), 'DES-ECB', hex2bin('00F283CDBA416FFF'), 1);

[bin2hex($dec)产生0367A67FC2000ADB

这对我来说很有意义...但是我需要能够仅从8位十六进制获得此结果,就像在线工具一样。我需要怎么做才能做到这一点?

php encryption openssl des ecb
1个回答
0
投票

产生差异的原因是padding。分组密码仅允许对长度对应于块大小的整数倍(在DES情况下为8字节)的数据进行加密。填充可通过根据特定逻辑添加数据来确保满足此条件。

有不同类型的填充。openssl_encrypt/ openssl_encrypt使用openssl_decryptopenssl_decrypt PKCS7-paddingdefault

PKCS7-padding将始终向明文添加数据,即使明文的长度已经是块大小的整数倍。在这种情况下,将添加一个完整的块(online-tool)。因此,对于以1块(8字节)为长度的纯文本,用Zero-padding生成的发布密文的长度为2块(16字节)。

[与PKCS7填充不同,如果明文的长度是块大小的倍数,则在线工具使用的零填充变体不会添加任何数据。因此,使用在线工具生成的发布密文的长度为1块(8字节),而明文的长度为1块(8字节)。

details / openssl_encrypt不支持零填充。为了使openssl_encrypt的密文与在线工具的密文相匹配,必须禁用PKCS7填充,并且必须实现在线工具使用的“零填充”变体。禁用填充是通过标志openssl_decrypt完成的,该标志必须使用第四个参数进行设置。 注意

:该标志的名称具有误导性:该标志不启用“零填充”,而仅禁用PKCS7填充。这意味着仍然必须手动实现在线工具的“零填充”变体。此外:在当前代码中,值openssl_encrypt在第四个参数中传递,该参数对应于标志OPENSSL_ZERO_PADDING。要设置两个标志,因此必须将值1替换为OPENSSL_RAW_DATA对于其长度已经对应于块大小的整数倍的纯文本,在线工具使用的禁用PKCS7填充和零填充变体都不会添加任何其他数据,因此密文匹配。在这种情况下,无需手动实现在线工具使用的“零填充”变体。

关于安全性的最后说明:1不安全。今天的标准是OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING。欧洲央行也不安全。更安全的DES例如CBC或GCM。

© www.soinside.com 2019 - 2024. All rights reserved.