PHP Conference Nagoya 2025

mcrypt_module_open

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

mcrypt_module_open使用するアルゴリズムおよびモードのモジュールをオープンする

警告

この関数は PHP 7.1.0 で 非推奨となり、PHP 7.2.0 で削除 されました。この関数に頼らないことを強く推奨します。

説明

mcrypt_module_open(
    string $algorithm,
    string $algorithm_directory,
    string $mode,
    string $mode_directory
): resource

この関数は、使用するアルゴリズムおよびモードのモジュールをオープン します。アルゴリズム名は、たとえば "twofish" のように名前で指定するか定数 MCRYPT_暗号名 のいずれかを使用して指定します。 ライブラリは mcrypt_module_close() をコールする ことによりクローズされます。

パラメータ

algorithm

MCRYPT_暗号名 定数のいずれか、 あるいはアルゴリズム名をあらわす文字列。

algorithm_directory

暗号化モジュールの位置を指定する際には algorithm_directory を使います。 ディレクトリ名を指定した場合には、これが使用されます。 これらの一つに空の文字列("")を指定した場合、php.ini ディレクティブ mcrypt.algorithms_dir に設定された値を使います。 これらが設定されていない場合、libmcrypt をコンパイルした際の デフォルトのディレクトリ (通常は/usr/local/lib/libmcrypt) を使います。

mode

定数 MCRYPT_MODE_モード名、あるいは文字列 "ecb", "cbc", "cfb", "ofb", "nofb" ,"stream" のいずれか。

mode_directory

暗号化モジュールの位置を指定する際には mode_directory を使います。 ディレクトリ名を指定した場合には、これが使用されます。 これらの一つに空の文字列("")を指定した場合、php.ini ディレクティブ mcrypt.modes_dir に設定された値を使います。 これらが設定されていない場合、libmcrypt をコンパイルした際の デフォルトのディレクトリ (通常は/usr/local/lib/libmcrypt) を使います。

戻り値

通常は暗号化記述子を返します。エラー時は false を返します。

例1 mcrypt_module_open() の例

<?php
$td
= mcrypt_module_open(MCRYPT_DES, '',
MCRYPT_MODE_ECB, '/usr/lib/mcrypt-modes');

$td = mcrypt_module_open('rijndael-256', '', 'ofb', '');
?>

上の例の最初の行では、デフォルトのディレクトリから DES 暗号化を、 そして /usr/lib/mcrypt-modes から ECB モードの オープンを試みます。2 行目の例では暗号化形式とモードを文字列で 指定しています。これは、libmcrypt 2.4.x あるいは 2.5.x に対して 拡張モジュールがリンクされている場合にのみ使用可能です。

例2 mcrypt_module_open() を暗号化で使用する

<?php
/* 暗号モジュールをオープンします */
$td = mcrypt_module_open('rijndael-256', '', 'ofb', '');

/* IV を作成し、キー長を定義します。Windows では、かわりに
* MCRYPT_RAND を使用します */
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_RANDOM);
$ks = mcrypt_enc_get_key_size($td);

/* キーを作成します (例示のみ: MD5 は、この用途には不向きなハッシュアルゴリズムです) */
$key = substr(hash('md5', 'very secret key'), 0, $ks);

/* 暗号化処理を初期化します */
mcrypt_generic_init($td, $key, $iv);

/* データを暗号化します */
$encrypted = mcrypt_generic($td, 'This is very important data');

/* 暗号化ハンドラを終了します */
mcrypt_generic_deinit($td);

/* 復号用の暗号モジュールを初期化します */
mcrypt_generic_init($td, $key, $iv);

/* 暗号化された文字列を復号します */
$decrypted = mdecrypt_generic($td, $encrypted);

/* 復号ハンドルを終了し、モジュールを閉じます */
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

/* 文字列を表示します */
echo trim($decrypted) . "\n";
?>

参考

add a note

User Contributed Notes 7 notes

up
2
Anonymous
21 years ago
Doing a trim($decrypted) will remove the null padding that may occur as a result of decryption.

The problem is if you're encrypting something like a MSWord document which can commonly end with nulls. The result $decrypted will be smaller than the original cleartext - which will then fail to open in MSOffice.

To get around this, make sure you store the length of the original cleartext, and when you decrypt it, do:

$decrypted = substr(mdecrypt_generic($td, $encrypted), 0, $originalLength);
up
2
Mark
12 years ago
for errors like
' mcrypt_module_open(): Could not open encryption module in '

Make sure you're using the right name. The page giving the list of ciphers is NOT the right way to say each cipher (shown here http://www.php.net/manual/en/mcrypt.ciphers.php).

In order to see what ones are supported, try phpinfo(); and look under mcrypt to find something like this

mcrypt support => enabled
mcrypt_filter support => enabled
Version => 2.5.8
Api No => 20021217
Supported ciphers => cast-128 gost rijndael-128 twofish arcfour cast-256 loki97 rijndael-192 saferplus wake blowfish-compat des rijndael-256
serpent xtea blowfish enigma rc2 tripledes
Supported modes => cbc cfb ctr ecb ncfb nofb ofb stream
up
1
dinamic at gmail dot com
17 years ago
Also it should be pointed that md5() and/or sha1() should not be used while forming your key for the mcrypt. This is so because hex encoding uses a set of only 16 characters [0-9a-f], which is equivalent to 4 bits, and thus halve the strength of your encryption: 4 x 32 = 128-bit.

I have re-wrote the example shown, so here is my suggestion to get real 256-bit encryption:

<?php
$key1
= "this is a secret key";
$key2 = "this is the second secret key";
$input = "Let us meet at 9 o'clock at the secret place.";
$length = strlen($input);

/* Open the cipher */
$td = mcrypt_module_open('rijndael-256', '', 'cbc', '');

/* Create the IV and determine the keysize length, use MCRYPT_RAND
* on Windows instead */
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$ks = mcrypt_enc_get_key_size($td);

/* Create key */
$key1 = md5($key1);
$key2 = md5($key2);

$key = substr($key1, 0, $ks/2) . substr(strtoupper($key2), (round(strlen($key2) / 2)), $ks/2);

$key = substr($key.$key1.$key2.strtoupper($key1),0,$ks);

/* Intialize encryption */
mcrypt_generic_init($td, $key, $iv);

/* Encrypt data */
$encrypted = mcrypt_generic($td, $input);

/* Terminate encryption handler */
mcrypt_generic_deinit($td);

/* Initialize encryption module for decryption */
mcrypt_generic_init($td, $key, $iv);

/* Decrypt encrypted string */
$decrypted = mdecrypt_generic($td, $encrypted);

/* Terminate decryption handle and close module */
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

/* Show string */
echo "Text: ".substr($decrypted,0,$length) . "<br>";
echo
"Encoded: ".$encrypted ."<br>";
echo
"<br>key1: $key1 <br>key2: $key2<br>created key: $key";
?>
up
0
royconejo
15 years ago
about the previous comments on hex formatting and capitalization as a way to improve the key:

this would seem pretty obvious, but it is a choice to be limited to only hex characters ([0-9a-z]); you can get the original RAW output from md5() or sha1() and not the default readable hex formatting.

the result of a raw output will be 16 o 20 (depending on the hash function being used) series of chars in the range 0-255. way better than [0-9a-z] and even [0-9a-zA-Z].

16 or 20 is generally lower than the maximum key lenght ($ks in the example), but you can append two or more keys together:

<?php
$human_key1
= 'something very secret';
$human_key2 = 'something else very secret';

// 40 bytes binary key using two "human readable" keys and sha1.
$bigger_binary_key = sha1($human_key1, true) . sha1($human_key2, true);

// then just use it as you would (extract taken from the example)
$key = substr($bigger_binary_key, 0, $ks);
?>

... or you can automatically split one large "human key" into two or more parts, hash those parts with sha1 (raw output!) and merge them together again (in original order or rearrange, salt, transform them as you like) to get a binary key of 40, 60, 80 or more chars depending on the number of parts the secret key has been splitted =)
up
-1
Anonymous
8 years ago
Follow up to anonymous with Windows' mcrypt_module_open() errors:

<?php
$M
= mcrypt_list_modes();
$A = mcrypt_list_algorithms();
foreach (
$M as $m)
foreach (
$A as $a) {
$t = @mcrypt_module_open($a,'',$m,'');
print
"$m, $a = ";
print (
$t)?"ok":"nope";
print
"<br>";
}
?>

This will show that not all modes work with all algorithmns. Cygwin also has no 'libmcrypt.dll' and it too will work with only some combinations.

(First tries just happened to be one of the ones that did not work!)
up
-1
lehmann*at*arcor-so.net
15 years ago
Keep in mind that the mcrypt functions do not implement padding like e.g. pkcs#5. This causes the problem with zero bytes at the end and the sting cannot be correctly decoded in other environments.

For an example how to add pkcs 5 padding, see ref.mcrypt.php
up
-2
ash
16 years ago
A slight improvement of dinamic's function to create a key:

I think the weak point is that capitals are always used in the same part of the string. The following code capitalizes random characters of the string, making the key less predictable:

<?php
$key
= substr($key1, 0, $ks/2) . substr($key2, (round(strlen($key2) / 2)), $ks/2);
$key = substr($key.$key1.$key2.$key1,0,$ks);

$buffer = str_split($key);

$limit = count($buffer)-1;
srand((float)microtime() * 1000000);

$end = rand(0, $limit);
$a = 0;

// replace random chars with capitals
while ($a < $end) {
list(
$usec, $sec) = explode(' ', microtime());
$seed = ((float)$sec) + ((float) $usec * 100000);
mt_srand($seed);

$index = mt_rand(0,$limit);

$buffer[$index] = strtoupper($buffer[$index]);
$a++;
}

$key = join('', $buffer);
?>
To Top