- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将项目中加密数据和使用 mcrypt 的所有功能迁移到 openssl。
进行测试时我发现,使用相同的 key 加密相同的数据会得到不同的结果。
解密时,我使用这两个函数都得到了正确的结果;问题是我与外部提供商共享此信息,并且只有使用 mcrypt 加密才能成功解密数据。
这是测试代码:
// Configuration.
$data = 'FOO';
$secret = '111222333444555666777888';
$iv = 'ABCDEFGH';
// Encrytp & decrypt with mcrypt.
$encMcrypt = bin2hex(mcrypt_encrypt(MCRYPT_3DES, $secret, utf8_encode($data), MCRYPT_MODE_CBC, $iv));
$decMcrypt = mcrypt_decrypt(MCRYPT_3DES, $secret, hex2bin($encMcrypt), MCRYPT_MODE_CBC, $iv);
// Encrytp & decrypt with openssl.
$encOpenSSL = bin2hex(openssl_encrypt(utf8_encode($data), 'DES-EDE3-CBC', $secret, OPENSSL_RAW_DATA, $iv));
$decOpenSSL = openssl_decrypt(hex2bin($encOpenSSL), 'DES-EDE3-CBC', $secret, OPENSSL_RAW_DATA, $iv);
// Result.
echo "mcrypt encrypt: $encMcrypt <br>";
echo "openssl encrypt: $encOpenSSL <br>";
echo "mcrypt decrypt: $decMcrypt <br>";
echo "openssl decrypt: $decOpenSSL";
结果:
mcrypt encrypt: 3f9bd8d5f844ff67
openssl encrypt: b2f4b9aeb07e1ca4
mcrypt decrypt: FOO
openssl decrypt: FOO
有谁知道为什么会得到不同的结果?
谢谢!
最佳答案
不同的是mcrypt_encrypt
/mcrypt_decrypt
使用Zero-Padding和 openssl_encrypt
/openssl_decrypt
使用PKCS7-Padding 。这可以通过为 openssl
应用零填充来轻松验证:为此,必须使用标志 OPENSSL_ZERO_PADDING
禁用 PKCS7-Padding(重要:尽管名称如此,此标志并不意味着使用零填充,而是根本不应用填充),并且明文必须使用 0
值填充到下一个整数倍 block 大小(对于 Triple-DES,8
字节),除非长度已对应于 block 大小的整数倍:
<?php
function zeroPadding($data, $size) {
$oversize = strlen($data) % $size;
return $oversize == 0 ? $data : ($data . str_repeat("\0", $size - $oversize));
}
// Something is wronguration.
$data = 'FOO';
$secret = '111222333444555666777888';
$iv = 'ABCDEFGH';
// Encrytp & decrypt with mcrypt.
$encMcrypt = bin2hex(mcrypt_encrypt(MCRYPT_3DES, $secret, utf8_encode($data), MCRYPT_MODE_CBC, $iv));
$decMcrypt = mcrypt_decrypt(MCRYPT_3DES, $secret, hex2bin($encMcrypt), MCRYPT_MODE_CBC, $iv);
// Encrytp & decrypt with openssl.
$encOpenSSLZeroPadding = bin2hex(openssl_encrypt(utf8_encode(zeroPadding($data, 8)), 'DES-EDE3-CBC', $secret, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv));
$decOpenSSLZeroPadding = openssl_decrypt(hex2bin($encOpenSSLZeroPadding), 'DES-EDE3-CBC', $secret, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
// Result.
echo "data padded: " . bin2hex(zeroPadding($data, 8)) . "<br>";
echo "mcrypt encrypt: $encMcrypt <br>";
echo "openssl encrypt: $encOpenSSLZeroPadding <br>";
echo "mcrypt decrypt: $decMcrypt <br>";
echo "mcrypt decrypt: " . bin2hex($decMcrypt) . "<br>";
echo "openssl decrypt: $decOpenSSLZeroPadding" . "<br>";
echo "openssl decrypt: " . bin2hex($decOpenSSLZeroPadding);
输出如下:
data padded: 464f4f0000000000
mcrypt encrypt: 3f9bd8d5f844ff67
openssl encrypt: 3f9bd8d5f844ff67
mcrypt decrypt: FOO
mcrypt decrypt: 464f4f0000000000
openssl decrypt: FOO
openssl decrypt: 464f4f0000000000
可以在 mcrypt
上下文中使用 PKCS7 填充,而不是在 openssl
上下文中使用零填充。无论使用这两种变体中的哪一种,使用相同的填充 mcrypt
和 openssl
结果都是相同的!
应该注意(请参阅十六进制输出),mcrypt
在解密过程中不会删除零填充(与 openssl
不同,它会在解密过程中删除 PKCS7-Padding) )。另外,零填充是 unreliable与 PKCS7-Padding 相比。如果要求允许(在您的情况下,由于外部提供者的原因可能不是这种情况),因此应该使用 PKCS7-Padding。
此外,两个发布的变体都使用相同的算法,即 Triple-DES在 CBC -模式。 Triple-DES 的 block 大小为 8
字节, key 大小为 24
字节。 Triple-DES 与 DES 不同,但它基于 DES,因为它由三个 DES 运行组成(加密-解密-加密 = ede)。 mcrypt
使用两个参数指定 Triple-DES/CBC:MCRYPT_3DES
(三重 DES)和 MCRYPT_MODE_CBC
(CBC 模式),而 openssl
仅使用一个参数,DES-EDE3-CBC
。
有几个Keying-Options对于三重 DES。 3TDEA
使用三个独立的 DES key ,并在 openssl
的上下文中使用 DES-EDE3-CBC
指定,它需要 24
字节 key ,2TDEA
使用两个独立的 key ,可以在 openssl
上下文中指定,也可以使用 DES-EDE-CBC
指定,其中需要 16
字节 key 。
Triple-DES 比现代 AES 慢得多,但具有相当的安全性。与填充一样,如果可能,您应该切换到 AES。
关于PHP 7.2 openssl_encrypt 和 mcrypt_encrypt 生成不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58234665/
根据 php 7.0 mcrypt_decrypt 已弃用。 我有以下代码。 $intSize= mcrypt_get_iv_size( MCRYPT_RIJNDAEL_256, MCRYPT_MOD
我正尝试在 CBC 模式下使用 256 位 key 使用 Rijndael 密码对 PHP 中的某些数据进行加密,但由于某种原因,我收到以下错误消息: mcrypt_encrypt() 模块初始化失败
我使用了 MCRYPT_ENCRYPT 和这个方法: class Encrypter { private static $Key = "dublin"; public static f
这是一个加密和解密数据的PHP演示脚本: \n"; $card_nbr_encrypted=encrypt_data($card_nbr); echo "card_nbr_encrypted: $ca
有人知道 mcrypt_generic 和 mcrypt_encrypt 在 PHP 加密方面的区别吗? 最佳答案 mcrypt_encrypt() 结合了几种方法的功能,而 mcrypt_gener
首先,Coldfusion Encrypt: #ciphertext# 然后,PHP mcrypt: $message = "1447841550"; $key = 'Mk9m98IfEblmP
这是一个加密和解密数据的PHP演示脚本: \n"; $card_nbr_encrypted=encrypt_data($card_nbr); echo "card_nbr_encrypted: $ca
我被迫从 PHP 5.6 迁移到 7.0+,除了 mcrypt_encrypt() 之外一切都很好,它已经被弃用,如 php.net 中所述。 这是我的代码 $json = array( 'A
我正在使用以下函数来加密字符串 ($str),并使用 key ($key) 来创建唯一 key 。 示例代码: 该函数返回由特殊字符(包括 '+' )组成的值。我将此值作为唯一 ID 存储在数据库中
我的 Web 应用程序从客户端获取 URL 对象,使用 mcrypt_encrypt 对其进行加密,并将结果作为 LONGTEXT 类型存储在 MySQL 数据库中。整个过程如下所示: /*
我一直在寻找答案,但在这里找不到。如果已经有人问过这个问题,请原谅。 我有一个加密和解密字符串的简单代码,字符串看起来一样,但是当使用 == 比较它们时,它们看起来并不相同,所以哈希值也不同.. 这是
我有一个旧算法来编码我想与 PHP 7 一起使用的密码 public function encriptarPass($cadena) { $extra = (strlen($cadena)%
我几乎失去了头发、思想和其他一切!我一直在尝试将此 PHP 函数转换为 C#: function encrypt_decrypt($action, $string) { $output = fa
我想知道是否有一个 javascript 库可以为 php 中的 mcrypt_encrypt 提供功能。 我正在编写一个函数来使用 javascript 访问我的 api。我总是对我的参数进行加密和
PHP 版本: mcrypt_encrypt(MCRYPT_RIJNDAEL_256, "11111111111111111111111111111111", "1111111111111111111
我需要在 android 中使用 key 对特定文本进行加密。在 PHP 中,加密代码如下所示 $this->securekey = hash('sha256',$textkey,TRUE); $th
function fnEncrypt($key,$string){ return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key
我需要加密一些 SOAP header 字段,目前我在 PHP 5.6 版本的项目中使用以下代码。 function getBaseEncoded($data, $key) { $size
我正在将项目中加密数据和使用 mcrypt 的所有功能迁移到 openssl。 进行测试时我发现,使用相同的 key 加密相同的数据会得到不同的结果。 解密时,我使用这两个函数都得到了正确的结果;问题
我正在将项目中加密数据和使用 mcrypt 的所有功能迁移到 openssl。 进行测试时我发现,使用相同的 key 加密相同的数据会得到不同的结果。 解密时,我使用这两个函数都得到了正确的结果;问题
我是一名优秀的程序员,十分优秀!