Upgrade to Pro — share decks privately, control downloads, hide ads and more …

忘れた頃にMcryptは廃止される

 忘れた頃にMcryptは廃止される

PHPerKaigi 2018 LT発表資料です。
https://phperkaigi.jp/2018/

sapi_kawahara

March 10, 2018
Tweet

More Decks by sapi_kawahara

Other Decks in Programming

Transcript

  1. 忘れた頃にMcryptは廃止さ
    れる
    さっぴー川原
    Facebook:kawahara.hideaki.0204
    Twitter:@sapi_kawahara

    View Slide

  2. 自己紹介
    ▪ 川原 英明(老眼進行中の49歳、PhpStormをナイトモードじゃないツ
    ライです)
    ▪ COEDOのふるさと川越に住んでます。
    ▪ 元ゲームエンジニアです。(ファミコン時代から開発してました、この当
    時のネタも語れます)
    ▪ スキルは、今はやってないアセンブラからC言語に始まって、今はPerl、
    PHP、Java、Pythonです、基本的にはなんでもやります!
    ▪ 今は、どこかの契約社員で、業務委託的なことをしてますが、今日は、
    そこのシステムじゃないです。

    View Slide

  3. Mcryptの廃止は、いきなり来た
    ▪ 自分の感覚では、Mcryptの廃止は、唐突にアナウンスがきたような気
    がします。
    ▪ PHP 7.1.0で非推奨、PHP 7.2.0で廃止と参考URLにも書いてありまし
    た。
    ▪ メジャーバージョンじゃなく、マイナーバージョンで廃止って、あんまり
    普通じゃない気がします。じゃない気がする。
    ▪ 参考 http://php.net/manual/ja/intro.mcrypt.php
    ▪ 警告 This feature was DEPRECATED in PHP 7.1.0, and REMOVED in PHP
    7.2.0.

    View Slide

  4. いいでしょう!Mcryptを抹殺しましょう!
    ▪ 更によく読むと、Mcryptのドキュメントには「十年近くにわたって放置されて
    おり」とあります。
    ▪ 自分は、これを良い機会だと思いました、PECLで使うのは単なる延命だ!
    ▪ Mcryptに関するレガシーなコードを抹殺するのが良いのでは?
    ▪ 推奨しているOpenSSLに行こうじゃないですか?!
    ▪ 参考:http://php.net/manual/ja/migration71.deprecated.php
    ▪ mcrypt 拡張モジュールは十年近くにわたって放置されており、極めて使いづらいもので
    す。 そこで、この拡張モジュールを非推奨にしました。かわりに OpenSSL を使いましょ
    う。 mcryptは PHP 7.2 でコアから削除されて、PECL に移る予定です。

    View Slide

  5. この先生きのこるには?
    ▪ Mcryptを抹殺するために、選択肢はどれになりますか?
    1. PECLに頼る。
    2. データを初期化して、OpenSSLに行く。
    3. データを初期化せずに、OpenSSLに行く。

    View Slide

  6. せっかくだから
    俺はこの 赤の扉を選ぶぜ!

    View Slide

  7. せっかくだから
    俺はこの 「データを初期化せずに、
    OpenSSLに行く」
    を選ぶぜ!

    View Slide

  8. 簡単な、ecbモードで確認する
    ▪ 簡単に確認したいので、ecbモードで確認する。
    ▪ ソースコードは、quitaに置いてます。
    ▪ https://qiita.com/hideaki0204/items/bbfbc57fd12ff348f216

    View Slide

  9. ソースコード1/2
    $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;

    View Slide

  10. ソースコード2/2
    // 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);
    }

    View Slide

  11. 出力結果1/6
    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: テストするための文字

    View Slide

  12. 出力結果2/6
    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

    View Slide

  13. 出力結果3/6
    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

    View Slide

  14. 出力結果4/6
    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

    View Slide

  15. 出力結果5/6
    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

    View Slide

  16. 出力結果6/6
    mcrypt_method: tripledes
    input message: テストするための文字
    openssl_method: not decrypt

    View Slide

  17. 結果
    ▪ 4つ、移行出来ることが判明!
    ▪ 自分の担当では、desとblowfishを使っていたので、OpenSSLに移行で
    きるのは嬉しい!
    ▪ Mcryptの抹殺が進められる!
    ▪ ただ、rijndael-192がダメだったのは残念でした。
    mcrypt_method openssl_method
    cast-128 cast5
    rijndael-128 aes-256
    des des
    blowfish bf

    View Slide

  18. 実は、まだ抹殺できてません
    ▪ rijndael-192を使っているのは、残念ながらPHP 5で生きてます。
    ▪ それ以外は、無事にPHP 7.2.0 で、OpenSSLに移行しました。
    ▪ 残る手は、McryptのデータをOpenSSLにコンバートする手ですが、ま
    だ決断には至っていません。

    View Slide

  19. この騒動で得たこと
    ▪ 大半のシステムでMcryptを抹殺できた、一部未完です。
    ▪ PHP 5.3.x から追加されたエラーレベル、E_DEPRECATEDは開発時に
    は、よく見るこよく見ること!ググると表示を消す方法が出てきて悲し
    いです。
    ▪ Mcrypt以外にも、レガシーなコードがあるのではないかと、ソースコー
    ドを見直す、きっかけにもなりました。
    ▪ 他にも、レガシーなコードでで抹殺するのが望ましいのがあれば、抹
    殺しようと思いました。

    View Slide

  20. LT後の補足
    • rijndael-192については、うまく行かなかった理由を検証をしてないで
    す。
    • もう少し、突っ込んで検証しておきたいのですが、それは宿題にさせ
    てください。

    View Slide