PHP Conference Japan 2024

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 * blocksize,则数据将用'\0'填充。

mode

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

iv

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

返回值

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

参见

添加注释

用户贡献的注释 7 条注释

32
eddiec at stararcher dot com
19 年前
看起来mcrypt_decrypt用空字符('\0')填充*返回字符串*以填充到n * blocksize。对于像我这样的老C程序员来说,很容易相信字符串在第一个空字符处结束。在PHP中并非如此

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

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

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

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

基于eddiec的代码,您可以使用以下代码删除空字符和EOT:

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

使用openssl从AES解密RIJNDAEL的方法是使用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。
2
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"));
我认为这不是解决这个问题的最佳方法,但我解决了我的问题 :)
0
evangelion207 at hotmail dot com
13年前
小心,有时mcrypt_decrypt会向未加密的字符串返回额外的空格;使用trim()删除它们。我花了大约2个小时搜索错误,结果就是这个..
-3
匿名用户
14年前
要删除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);
?>
To Top