mdecrypt_generic

(PHP 4 >= 4.0.2, PHP 5, PHP 7 < 7.2.0, PECL mcrypt >= 1.0.0)

mdecrypt_generic解密数据

警告

此函数从 PHP 7.1.0 开始已 弃用,从 PHP 7.2.0 开始已 移除。强烈建议不要依赖此函数。

描述

mdecrypt_generic(resource $td, string $data): string

此函数解密数据。请注意,由于数据的填充,返回字符串的长度实际上可能比未加密字符串的长度更长。

参数

td

mcrypt_module_open() 返回的加密描述符

data

加密数据。

返回值

返回解密后的字符串。

示例

示例 #1 mdecrypt_generic() 示例

<?php
/* 数据 */
$key = '这是一个非常长的密钥,甚至对于密码来说也过于长了';
$plain_text = '非常重要的数据';

/* 打开模块并创建 IV */
$td = mcrypt_module_open('des', '', 'ecb', '');
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
$iv_size = mcrypt_enc_get_iv_size($td);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

/* 初始化加密句柄 */
if (mcrypt_generic_init($td, $key, $iv) != -1) {

/* 加密数据 */
$c_t = mcrypt_generic($td, $plain_text);
mcrypt_generic_deinit($td);

/* 重新初始化缓冲区以进行解密 */
mcrypt_generic_init($td, $key, $iv);
$p_t = mdecrypt_generic($td, $c_t);

/* 清理 */
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}

if (
strncmp($p_t, $plain_text, strlen($plain_text)) == 0) {
echo
"ok\n";
} else {
echo
"error\n";
}
?>

上面的示例展示了如何检查加密前的数据是否与解密后的数据相同。在尝试解密数据之前,使用 mcrypt_generic_init() 重新初始化加密缓冲区非常重要。

在调用此函数之前,应该始终使用密钥和 IV 使用 mcrypt_generic_init() 初始化解密句柄。在完成加密的地方,应该通过调用 mcrypt_generic_deinit() 释放加密缓冲区。请参阅 mcrypt_module_open() 获取示例。

另请参阅

添加备注

用户贡献的备注 11 个备注

6
nytro_rst at yahoo dot com
15 年前
<?php
// 参数:
// $text = 要加密的文本。
// $key = 用于加密的密钥。
// $alg = 算法。
// $crypt = 1 如果要加密,0 如果要解密。

function cryptare($text, $key, $alg, $crypt)
{
$encrypted_data="";
switch(
$alg)
{
case
"3des":
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
break;
case
"cast-128":
$td = mcrypt_module_open('cast-128', '', 'ecb', '');
break;
case
"gost":
$td = mcrypt_module_open('gost', '', 'ecb', '');
break;
case
"rijndael-128":
$td = mcrypt_module_open('rijndael-128', '', 'ecb', '');
break;
case
"twofish":
$td = mcrypt_module_open('twofish', '', 'ecb', '');
break;
case
"arcfour":
$td = mcrypt_module_open('arcfour', '', 'ecb', '');
break;
case
"cast-256":
$td = mcrypt_module_open('cast-256', '', 'ecb', '');
break;
case
"loki97":
$td = mcrypt_module_open('loki97', '', 'ecb', '');
break;
case
"rijndael-192":
$td = mcrypt_module_open('rijndael-192', '', 'ecb', '');
break;
case
"saferplus":
$td = mcrypt_module_open('saferplus', '', 'ecb', '');
break;
case
"wake":
$td = mcrypt_module_open('wake', '', 'ecb', '');
break;
case
"blowfish-compat":
$td = mcrypt_module_open('blowfish-compat', '', 'ecb', '');
break;
case
"des":
$td = mcrypt_module_open('des', '', 'ecb', '');
break;
case
"rijndael-256":
$td = mcrypt_module_open('rijndael-256', '', 'ecb', '');
break;
case
"xtea":
$td = mcrypt_module_open('xtea', '', 'ecb', '');
break;
case
"enigma":
$td = mcrypt_module_open('enigma', '', 'ecb', '');
break;
case
"rc2":
$td = mcrypt_module_open('rc2', '', 'ecb', '');
break;
default:
$td = mcrypt_module_open('blowfish', '', 'ecb', '');
break;
}

$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);

if(
$crypt)
{
$encrypted_data = mcrypt_generic($td, $text);
}
else
{
$encrypted_data = mdecrypt_generic($td, $text);
}

mcrypt_generic_deinit($td);
mcrypt_module_close($td);

return
$encrypted_data;
}
?>
4
jakub dot lopuszanski at nasza-klasa dot pl
11 年前
对于那些对填充感到“惊讶”的人(即使它在方法描述中提到),请不要仅仅“删除我不理解的所有内容”。
使用 rtrim,rtrim "\0",删除所有字符码 < 16 等方法都是错误的。
PKCS #7 填充的工作原理与 RFC 5652 中描述的一样。
要删除它,只需查看消息的最后一个字节,它会告诉你需要删除多少字节。
例如,如果最后一个字节等于 \0A,则删除 10 个字节。
2
Ulysse
10 年前
根据“jakub dot lopuszanski at nasza-klasa dot pl”提供的信息,在 PKCS#7 中,最后一个字节包含要删除的字节数(参见 RFC 5652,第 6.3 部分),以及像我一样喜欢复制粘贴现成代码段的人

<?php
function unpadPKCS7($data, $blocksize)
{
$last = substr($data, -1);
return
substr($data, 0, strlen($data) - ord($last));
}
?>

现在你没有理由再使用 rtrim() 来删除结果末尾的填充了。
2
Anonymous
15 年前
这里是一个快速删除 PKCS7 填充的代码片段

<?php
function unpadPKCS7($data, $blockSize) {
$length = strlen ( $data );
if (
$length > 0) {
$first = substr ( $data, - 1 );

if (
ord ( $first ) <= $blockSize) {
for(
$i = $length - 2; $i > 0; $i --)
if (
ord ( $data [$i] != $first ))
break;

return
substr ( $data, 0, $i );
}
}
return
$data;
}
?>
2
Peter Bailey
12 年前
我们发现有时生成的填充不是空字符 "\0",而是几个控制字符中的一个。

如果你知道你的数据不应该有任何尾随的控制字符“就像我们一样”,你可以像这样删除它们。

<?php

$data
= mdecrypt_generic( $cipher, $data );

// 去除尾部控制字符填充
$data = preg_replace( "/\p{Cc}*$/u", "", $data );

?>
2
trashmail dot hashishin at gmail dot com
14 年前
无论何时您需要解密使用 dot.net(和其他?)加密的文件,都可以使用以下设置

加密:'rijndael-256'
模式:'cbc'
填充模式:Zeros
iv: "yes"

使用 base64 编码数据以将其发送到您的 php 脚本
1
robbie [at] averill [dot] co [dot] nz
19 年前
我注意到,有时当二进制密文比明文更长时,解密后的明文旁边可能会有一些小方框/正方形作为“填充”。我还注意到您不能剪切粘贴它们以编辑它们,但我找到了一个解决方案。

只需在字符串周围调用 rtrim(),它就会删除它们。
0
Silvan
16 年前
通常不建议只使用 rtrim 来删除填充。

对于不以“\0”结尾的字符串,请使用 rtrim($str, "\0"),或者在加密期间存储数据长度。
(尽管包含“\0”的数据有时会在加密过程中损坏,因此这些类型的数据实际上应该被打包。)

例如

<?php

function encrypt($original_data)
{
$length = strlen($original_data);
$data_to_encrypt = $length.'|'.$original_data;
// 加密包含其长度的数据。
// 不要保存未加密的长度,因为这可能是一个(较小的)安全风险
}

function
decrypt($cypher)
{
// 首先解密密文数据
// 接下来检索原始数据
list($length, $padded_data) = explode('|', $decrypted_data, 2);
$original_data = substr($padded_data, 0, $length);
}

?>
0
php at pcwize dot com
17 年前
只是确认 .DLL 问题。对于 4.3.4,您需要使用旧的 .DLL。我猜 PHP4 的任何版本都需要旧的 .DLL。对于 PHP5,您需要使用较新的版本。
0
drew at expressdynamics dot com
19 年前
在使用 PHP 5 的 Win32 系统上,您必须使用较新的 libmcrypt.dll 文件,否则 mdecrypt_generic 将无法工作。
0
jon@jonroig dot com
20 年前
这是一段加密/解密代码。

如果您在 win32 平台上使用它,请注意!最新的 DLL(2004 年 1 月 19 日)包含一个错误,阻止 mdecrypt_generic 正常运行。几乎让我崩溃……2002 年 12 月 30 日版本似乎可以正常运行。
<?

$key = "this is a secret key";
$input = "Let us meet at 9 o'clock at the secret place.";

$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$encrypted_data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

echo "加密: ".$encrypted_data;

echo "<br><br>";

$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$decrypted_data = mdecrypt_generic($td, $encrypted_data);
echo "解密: ".$decrypted_data;
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

?>
To Top