CakeFest 2024: The Official CakePHP Conference

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" для того, чтобы их размер стал кратен размеру блока. Эта функция возвращает зашифрованные данные. Обратите внимание, что длина возвращаемой строки может быть больше исходной из-за дополнения.

Если вы хотите хранить шифрованные данные в базе данных, убедитесь, что вы сохраняете строку полностью, как она была возвращена этой функцией, иначе вы потом не сможете её расшифровать. Если ваша оригинальная строка была 10 символов длиной, а размер блока равен 8 (используйте mcrypt_enc_get_block_size() для определения размера блока), то размер столбца базы данных должен быть как минимум 16 символов. Обратите внимание, что строка возвращаемая mdecrypt_generic() также будет размером 16 символов. В таком случае просто используйте rtrim($str, "\0") для удаления добавленных символов.

К примеру, если вы сохраните данные в MySQL, помните, что при вставке значений в поля типа VARCHAR, у них автоматически отбрасываются пробелы из конца строки. Если зашифрованные данные кончаются на пробел (ASCII 32), то они будут повреждены при такой вставке. Лучше используйте для хранения поля типа TINYBLOB/TINYTEX или больше.

Список параметров

td

Дескриптор шифрования.

Обработчик шифрования всегда должен инициализироваться с помощью mcrypt_generic_init() с ключом и инициализирующим вектором перед вызовом функции. Как только шифрование завершено, необходимо освободить буферы шифрования путём вызова функции mcrypt_generic_deinit(). Смотрите пример в описании функции mcrypt_module_open().

data

Данные для шифрования.

Возвращаемые значения

Возвращает зашифрованные данные.

Смотрите также

  • mdecrypt_generic() - Дешифровка данных
  • mcrypt_generic_init() - Функция инициализирует все буферы, необходимые для шифрования
  • mcrypt_generic_deinit() - Эта функция деинициализирует модуль шифрования

add a note

User Contributed Notes 7 notes

up
5
tmacedo at linux dot ime dot usp dot br
17 years ago
completing the post from Ryan Thomas, ryanrst at gmail dot com, if u post a cookie w/ HTTP method, its may be encoded;
As some chars in base64 will be encoded to another things, u can just replace them before encode and after decode;
Its a tweak from dawgeatschikin at hotmail dot com to original idea from massimo dot scamarcia at gmail dot com
(see @ http://www.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);
}
?>
up
1
Ryan Thomas, ryanrst at gmail dot com
18 years ago
If you wish to store encrypted data in a cookie variable on the browser you will encounter problems when decrypting the data. This is because cookies will only store US-ASCII characters and your encrypted data may contain non-US-ASCII characters.

The solution:

base64_encode your encrypted string before you store it in the cookie and base64_decode the string stored in the cookie becore decrypting.

Example:

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

function getEncryptedCookie($cookieName)
{
return $this->decrypt(base64_decode($_COOKIE[$cookieName]));
}
up
1
chad 0x40 herballure 0x2e com
17 years ago
If the data is already n*blocksize long, PHP pads with another full block of "\0", so there will be between 1 and mcrypt_enc_get_block_size($td) bytes of padding.

You can create binary-safe padding by unconditionally adding a 0x80 to the string, then stripping trailing "\0"s PHP added, plus the one 0x80 byte.

<?php
function pad($text) {
// Add a single 0x80 byte and let PHP pad with 0x00 bytes.
return pack("a*H2", $text, "80");
}
function
unpad($text) {
// Return all but the trailing 0x80 from text that had the 0x00 bytes removed
return substr(rtrim($text, "\0"), 0, -1);
}
?>
up
1
chad 0x40 herballure 0x2e com
17 years ago
Addendum to my previous note: apparently there was some sort of character encoding breakage; PHP does not pad if no padding is needed, and the extra padding I saw was the result of chr(X) returning multiple bytes or something.

The pad/unpad functions I gave are still binary-safe, though, and are to the best of my knowledge completely compatible with NIST 800-38a.
up
0
maxximus007 at gmail dot com
16 years ago
Behaviour change: Since 5.2.x mcrypt_generic will issue a warning when the datastring is empty.
up
0
eric at ez-llc dot com
18 years ago
I was able get php and perl to play together with blowfish using cipher block chaining. The blowfish key needs to be atleast 8 chars (even though blowfish min is 8 bits, perl didn't like keys smaller than 8 chars) and max 56. The iv must be exactly 8 chars and padding needs to be null because php pads with nulls. Also, php needs libmcrypt >= 2.4.9 to be compatible with 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 = 'my secret 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 : ".$encrypted;
echo "<br>";
echo "decrypted : ".$decrypted;
up
-3
pauls at sellingsource dot com
20 years ago
If you are encrypting binary and there is a null terminator partway through your encryption, you will loose the rest of the string. A workaround is to base64_encode your binary string first.

We found this problem while trying to encrypt CC information. Some CC values would not decrypt after we converted them to a binary string.

We were using the MCRYPT_RIJNDAEL_256 module to encrypt with.

Hope this helps someone.
To Top