mcrypt_generic

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

mcrypt_generic此函数加密数据

警告

此函数已于 PHP 7.1.0 版中 弃用,并在 PHP 7.2.0 版中 移除。强烈建议不要依赖此函数。

描述

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

此函数加密数据。数据将使用 "\0" 进行填充,以确保数据长度为 n * 块大小。此函数返回加密后的数据。请注意,由于数据的填充,返回字符串的长度实际上可能比输入更长。

如果要将加密后的数据存储在数据库中,请确保存储 mcrypt_generic 返回的整个字符串,否则字符串将无法完全正确解密。如果原始字符串长度为 10 个字符,块大小为 8(使用 mcrypt_enc_get_block_size() 确定块大小),那么数据库字段中至少需要 16 个字符。请注意,mdecrypt_generic() 返回的字符串也为 16 个字符……使用 rtrim($str, "\0") 移除填充。

例如,如果将数据存储在 MySQL 数据库中,请记住 varchar 字段会在插入时自动移除尾随空格。由于加密数据可能以空格(ASCII 32)结尾,因此此移除操作会导致数据损坏。请改用 tinyblob/tinytext(或更大的)字段存储数据。

参数

td

加密描述符。

加密句柄应始终使用 mcrypt_generic_init() 初始化密钥和 IV,然后才能调用此函数。在进行加密的地方,应通过调用 mcrypt_generic_deinit() 释放加密缓冲区。请参见 mcrypt_module_open() 以获取示例。

data

要加密的数据。

返回值

返回加密后的数据。

参见

添加注释

用户贡献的注释 7 个注释

5
tmacedo at linux dot ime dot usp dot br
17 年前
补充 Ryan Thomas 的帖子,ryanrst at gmail dot com,如果使用 HTTP 方法发布 Cookie,则可能需要对其进行编码;
由于 base64 中的某些字符将被编码为其他内容,您只需在编码之前和解码之后替换它们即可;
这是 dawgeatschikin at hotmail dot com 对 massimo dot scamarcia at gmail dot com 的原始想法进行的调整
(参见 @ https://php.net/manual/en/function.base64-encode.php)
<?php
function urlsafe_b64encode($string)
{
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_','.'),$data);
return
$data;
}
function
urlsafe_b64decode($string)
{
$data = str_replace(array('-','_','.'),array('+','/','='),$string);
$mod4 = strlen($data) % 4;
if (
$mod4) {
$data .= substr('====', $mod4);
}
return
base64_decode($data);
}
?>
1
Ryan Thomas, ryanrst at gmail dot com
18 年前
如果要将加密数据存储在浏览器的 Cookie 变量中,在解密数据时会遇到问题。这是因为 Cookie 只会存储 US-ASCII 字符,而加密数据可能包含非 US-ASCII 字符。

解决方案

在将加密字符串存储在 Cookie 中之前,请使用 base64_encode 对其进行编码,并在解密之前,请使用 base64_decode 对存储在 Cookie 中的字符串进行解码。

示例

function setEncryptedCookie($cookieName, $data)
{
setcookie($cookieName, base64_encode($this->encrypt($data)), time()+$this->expire);
}

function getEncryptedCookie($cookieName)
{
return $this->decrypt(base64_decode($_COOKIE[$cookieName]));
}
1
chad 0x40 herballure 0x2e com
18 年前
如果数据已经是 n*块大小的长度,PHP 会再添加一个完整的 "\0" 块,因此填充字节数将在 1 到 mcrypt_enc_get_block_size($td) 之间。

您可以通过无条件地向字符串添加 0x80 来创建二进制安全的填充,然后剥离 PHP 添加的尾随 "\0",以及 0x80 字节。

<?php
function pad($text) {
// 添加一个 0x80 字节,让 PHP 使用 0x00 字节进行填充。
return pack("a*H2", $text, "80");
}
function
unpad($text) {
// 返回除尾随 0x80 之外的所有内容,该内容已移除 0x00 字节
return substr(rtrim($text, "\0"), 0, -1);
}
?>
1
chad 0x40 herballure 0x2e com
18 年前
补充我之前的注释:显然存在某种字符编码问题;如果不需要填充,PHP 不会进行填充,而我看到的额外填充是 chr(X) 返回多个字节或其他原因导致的。

但是,我给出的 pad/unpad 函数仍然是二进制安全的,并且据我所知,它们完全兼容 NIST 800-38a。
0
maxximus007 at gmail dot com
16 年前
行为更改:从 5.2.x 版开始,当数据字符串为空时,mcrypt_generic 会发出警告。
0
eric at ez-llc dot com
18 年前
我能够使用 Blowfish 和密码块链接让 PHP 和 Perl 协同工作。Blowfish 密钥至少需要 8 个字符(尽管 Blowfish 的最小长度为 8 位,但 Perl 不喜欢小于 8 个字符的密钥),最大为 56 个字符。IV 必须正好为 8 个字符,填充需要为 null,因为 PHP 使用 null 进行填充。此外,PHP 需要 libmcrypt >= 2.4.9 才能与 Perl 兼容。

PERL
----

use Crypt::CBC;
$cipher = Crypt::CBC->new( {'key' => 'my secret key',
'cipher'=> 'Blowfish',
'iv' => '12345678',
'regenerate_key' => 0,
'padding' => 'null',
'prepend_iv' => 0
});
$cc = 'my secret text';
$encrypted = $cipher->encrypt($cc);
$decrypted = $cipher->decrypt($encrypted);

print "encrypted : ".$encrypted;
print "<br>";
print "decrypted : ".$decrypted;

PHP
---

$cc = 'my secret text';
$key = '我的秘密密钥';
$iv = '12345678';

$cipher = mcrypt_module_open(MCRYPT_BLOWFISH,'','cbc','');

mcrypt_generic_init($cipher, $key, $iv);
$encrypted = mcrypt_generic($cipher,$cc);
mcrypt_generic_deinit($cipher);

mcrypt_generic_init($cipher, $key, $iv);
$decrypted = mdecrypt_generic($cipher,$encrypted);
mcrypt_generic_deinit($cipher);

echo "加密后: ".$encrypted;
echo "<br>";
echo "解密后: ".$decrypted;
-3
pauls at sellingsource dot com
21 年前
如果您正在加密二进制数据,并且在加密过程中遇到了空终止符,则会丢失字符串的其余部分。解决方法是先对二进制字符串进行 base64_encode 编码。

我们在尝试加密信用卡信息时发现了这个问题。一些信用卡值在转换为二进制字符串后无法解密。

我们使用 MCRYPT_RIJNDAEL_256 模块进行加密。

希望这能帮助到某人。
To Top