mcrypt_decrypt

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

mcrypt_decrypt使用给定参数解密密文

警告

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

说明

mcrypt_decrypt(
    字符串 $cipher,
    字符串 $key,
    字符串 $data,
    字符串 $mode,
    字符串 $iv = ?
): 字符串|false

解密 data 并返回未加密的数据。

参数

cipher

其中一个 MCRYPT_ciphername 常量,或算法名称作为字符串。

key

用于加密数据的密钥。如果提供的密钥大小不受密码支持,则该函数将发出警告并返回 false

data

将使用给定 ciphermode 解密的数据。如果数据的大小不是 n * 块大小,则数据将用 '\0' 填充。

mode

其中一个 MCRYPT_MODE_modename 常量,或以下字符串之一:“ecb”、“cbc”、“cfb”、“ofb”、“nofb” 或 “stream”。

iv

用于 CBC、CFB、OFB 模式中的初始化,以及 STREAM 模式中某些算法中的初始化。如果提供的 IV 大小不受链接模式支持,或者没有提供 IV,但链接模式需要 IV,则该函数将发出警告并返回 false

返回值

返回解密后的数据,为字符串,或在失败时返回 false

参见

添加备注

用户贡献的备注 8 个备注

eddiec at stararcher dot com
19 年前
似乎 mcrypt_decrypt 用空字符 ('\0') 填充*返回值字符串*,以填充到 n * 块大小。对于像我这样的老 C 程序员来说,很容易认为字符串在第一个空字符处结束。在 PHP 中,它不是这样的

strlen("abc\0\0") 返回 5,而不是 3
strcmp("abc", "abc\0\0") 返回 -2,而不是 0

当将从 mycrypt_decrypt 返回的字符串传递给 NuSoap 消息时,我痛苦地吸取了这个教训,该消息很乐意将空字符传递给接收方,接收方无法弄清楚我在说什么。

我的解决方案是
<?php
$retval
= mcrypt_decrypt( ...etc ...);
$retval = rtrim($retval, "\0"); // 仅修剪末尾的空字符
?>
gmmarco at outlook dot my
6 年前
查看 https://php.net/manual/en/function.openssl-decrypt.php 以了解替代方法。

支持 PHP 5 >= 5.3.0、PHP 7
david at sickmiller dot com
15 年前
如果你碰巧在解密用 ColdFusion 加密的内容,你会发现它的加密函数似乎用 ASCII 4(“传输结束”字符)填充明文。

在 eddiec 的代码基础上,你可以使用以下代码删除空字符和 EOT 字符:

<?php
$retval
= mcrypt_decrypt( ...etc ...);
$retval = rtrim($retval, "\0\4"); // 仅修剪末尾的空字符和 EOT 字符
?>
beltrachi
12 年前
注意,MCRYPT_RIJNDAEL_256 不等效于 AES_256。

要使 RIJNDAEL 用 openssl 从 AES 解密,可以使用 MCRYPT_RIJNDAEL_128,并在加密前使用以下函数填充要加密的字符串:

<?php
function pkcs5_pad ($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return
$text . str_repeat(chr($pad), $pad);
}
?>

在解密时,选择 AES_256 或 AES_128 等,取决于加密中使用的密钥大小。在我的情况下,它是一个 128 位密钥,因此我使用了 AES_128。
pnz dot r00t at yandex dot ru
8 年前
使用此函数时,我发现了一些问题,在解码消息中添加了额外的二进制符号。
$sDecrypt – «2433091»
$sDecrypt strlen – 16(修剪前)
$sDecrypt – «2433091»
$sDecrypt strlen – 7(修剪后)
在本地 PC 上,这个问题通过使用 trim/trim 解决,但如果将加密消息发送到服务器并尝试加密,我发现我的消息不是 16 个符号(就像在我的本地 PC 中一样),而是 32 个符号,在编码后。 trim 函数不起作用。我查看了符号代码,发现
50
52
51
51
48
57
49
0
0
0
0
0
0
0
0
0
10
158
112
183
154
27
95
85
42
35
95
54
227
41
179
77
在“制表符符号”之后,我得到了一些垃圾符号,我像这样解决了这个问题。
在 mcrypt_decrypt 之后,我使用以下代码:
$plaintext_dec = substr($plaintext_dec, 0, strpos($plaintext_dec, "\0"));
我认为这不是解决这个问题的最佳方法,但我解决了我的问题 :)
evangelion207 at hotmail dot com
13 年前
小心,有时 mcrypt_decrypt 会向未加密的字符串返回额外的空格;使用 trim() 删除它们。我花了 2 个小时寻找错误,结果是这个…
Anonymous
13 年前
要删除 PKCS7 填充

<?php
$decrypted
= mdecrypt_generic($td, base64_decode($enc_auth_token));
$dec_s = strlen($decrypted);
$padding = ord($decrypted[$dec_s-1]);
$decrypted = substr($decrypted, 0, -$padding);
?>
artaxerxes2 at iname dot com
11 年前
要解密来自 MySQL 的 AES_ENCRYPT 函数的数据

<?php

function mysql_aes_key($key)
{
$new_key = str_repeat(chr(0), 16);
for(
$i=0,$len=strlen($key);$i<$len;$i++)
{
$new_key[$i%16] = $new_key[$i%16] ^ $key[$i];
}
return
$new_key;
}

function
aes_decrypt($encrypted,$key)
{
// if $encrypted is HEXed, then return it to binary
$encrypted = pack('H*',$encrypted);

$key = mysql_aes_key($key);
return
rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$key,$encrypted,MCRYPT_MODE_ECB,''),"\x00..\x1F");
}

?>

改编自网上某处找到的“使用 PHP 复制 MySQL AES 加密方法”文章(日期:2012-05-20)。
To Top