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

この関数は、データを暗号化します。データ長を n * blocksize とする ために、データは "\0" で埋められます。 この関数は、暗号化されたデータを返します。 データのパディングが行われるため、返される文字列の長さは 入力よりも長いことがあることに注意してください。

暗号化したデータをデータベースに格納する場合は、mcrypt_generic が返す文字列全てを格納することを忘れないでください。さもないと、 文字列を適切に復号できなくなります。もとの文字列が 10 文字で ブロックサイズが 8 (ブロックサイズを調べるには mcrypt_enc_get_block_size() を使用します) だった場合、データベースのフィールドには少なくとも 16 文字が 必要です。mdecrypt_generic() が返す文字列も 16 文字となることに注意しましょう。埋められた文字を取り除くには... rtrim($str, "\0") を使用します。

もし MySQL データベースにデータを格納する場合は、 varchar フィールドに値を挿入する際に末尾のスペースが取り除かれることを 覚えておきましょう。暗号化されたデータの最後にスペース(ASCII 32)が 含まれていた場合、この処理によってデータが破壊されてしまいます。 かわりに tinyblob/tinytext (あるいはより大きな) フィールドを 使用してください。

パラメータ

td

暗号化記述子。

この関数をコールする前には、常にキーと IV を用いて mcrypt_generic_init() で暗号化ハンドルを 初期化しておくべきです。暗号化が終了したら、 mcrypt_generic_deinit() をコールして 暗号化バッファを開放すべきです。使用例は mcrypt_module_open() を参照ください。

data

暗号化するデータ。

戻り値

暗号化したデータを返します。

参考

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