search
LoginSignup
30

More than 3 years have passed since last update.

posted at

updated at

PHP 7.2で消えるMcryptの扱い

deprecated(非推奨)を放置してませんか?

  • deprecatedにされた関数は、最後は消える運命にあります。
  • Mcryptも、http://php.net/manual/ja/migration71.deprecated.php のページに書かれているように、非推奨後に削除されることが記載されていました。

mcrypt 拡張モジュールは十年近くにわたって放置されており、極めて使いづらいものです。 そこで、この拡張モジュールを非推奨にしました。かわりに OpenSSL を使いましょう。 mcryptは PHP 7.2 でコアから削除されて、PECL に移る予定です。

  • 10年も放置ということは、 正直言ってPECLに行って使い続けるのも不安です。
  • この際、思い切って推奨しているOpenSSLに行こうじゃないですか?!

Mcryptはいきなり来た

  • そもそも、Mcryptは唐突に廃止のアナウンスがきたような気がします。
  • 確認すると、PHP 7.1.0で非推奨、PHP 7.2.0で廃止となりました!
  • モジュールの削除なのに、マイナーバージョンアップでくるとは、意外といきなりでした。
  • This feature was DEPRECATED in PHP 7.1.0, and REMOVED in PHP 7.2.0. FireShot Capture 6 - PHP_ はじめに - Manual - http___php.net_manual_ja_intro.mcrypt.php.png

この先生きのこるには?

  • 選択肢は3つ!
    1. PECLに頼る。
    2. データを初期化して、opensslに行く。
    3. データを初期化せずに、opensslに行く。

データを初期化せずに、opensslに行く。

  • せっかくだから俺はこの 赤の扉 「データを初期化せずに、opensslに行く」を選ぶぜ!
  • 行けるのか?試してみた!
  • とりあえず、簡単に試してみたいのでecbモードでやります。
test_code.php
<?php
$message = 'テストするための文字';
$key = '01234567890123456789012345678901234567890';

// opensslの利用可能な暗号メソッドを取得
$ciphers             = openssl_get_cipher_methods();

// mcryptの利用可能な暗号メソッドを取得
$algorithms = mcrypt_list_algorithms();

// mcryptの暗号の分、ループする
foreach($algorithms as $mcrypt_method) {
  // ブロックサイズ0は今回は対象外
  $size = @mcrypt_get_block_size($mcrypt_method , 'ecb');
  if ($size == null) {
  } else {

    echo "mcrypt_method: ${mcrypt_method} \n";
    echo "input message: {$message} \n";
    // 暗号化する文字列を取得したブロックサイズでpaddingする
    $padding_message = pkcs5_pad($message , $size);
    // mcrypt_get_key_sizeで、最小のキー長さを取得し、その長さをキーとする
    $setting_key = substr ($key , 0, mcrypt_get_key_size($mcrypt_method, 'ecb'));
    // mcryptで暗号化実行
    $crypto = base64_encode(mcrypt_encrypt($mcrypt_method, $setting_key, $padding_message, MCRYPT_MODE_ECB));

    // opensslで確認する
    $has_decrypt = false;

    // opensslの暗号の分、ループする
    foreach($ciphers as $openssl_method) {
       if (preg_match('/ecb\z/', $openssl_method)) {
         // decryptする
         $decrypt = openssl_decrypt($crypto, $openssl_method ,$setting_key );
         // decryptして入力文字列と一致したらOKとする
         if ($message == $decrypt) {
            echo "openssl_method: ${openssl_method} is OK\n";
            echo "decrypt message: {$decrypt} \n\n";
            $has_decrypt = true;
            break;
         }
      }
    }
    if ($has_decrypt == false) {
       echo "openssl_method: not decrypt \n\n";
    }
  }
}

function pkcs5_pad ($text, $blocksize)
{
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr($pad), $pad);
}

結果

mcrypt_method: cast-128 
input message: テストするための文字 
openssl_method: cast5-ecb is OK
decrypt message: テストするための文字 

mcrypt_method: gost 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: rijndael-128 
input message: テストするための文字 
openssl_method: aes-256-ecb is OK
decrypt message: テストするための文字 

mcrypt_method: twofish 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: cast-256 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: loki97 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: rijndael-192 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: saferplus 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: blowfish-compat 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: des 
input message: テストするための文字 
openssl_method: des-ecb is OK
decrypt message: テストするための文字 

mcrypt_method: rijndael-256 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: serpent 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: xtea 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: blowfish 
input message: テストするための文字 
openssl_method: bf-ecb is OK
decrypt message: テストするための文字 

mcrypt_method: rc2 
input message: テストするための文字 
openssl_method: not decrypt 

mcrypt_method: tripledes 
input message: テストするための文字 
openssl_method: not decrypt 

4つ行ける!

mcrypt_method openssl_method
cast-128 cast5
rijndael-128 aes-256
des des
blowfish bf
  • 自分が担当しているのはシステムで使っているのは、desとblowfishとrijndael-192・・・あれ?
  • rijndael-192はダメか・・・諦めるかな?←こちら、うまくいかなかった理由は未検証です。
  • PHP 5.3.0 ぐらいから、非推奨としてくれてたら、間に合ったかもしれませんが、後の祭りです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
30