概要
Redhat系のOSを使っている方は、そろそろPHPのバージョンが5系からアップデートする時期が迫っていると思います。 PHPの5.Xから7.2以上に上げるときに困るのが Mcrypt関数 の廃止です。
移行先として推奨されているOpenSSLへの単純な移行だと復号が出来なくなってしまいます。 そこで Mcrypt から OpenSSL に代替した場合でも、復号可能なコードの実装例を紹介します。
参考
https://github.com/LancersDevTeam/PHP_versionup/blob/master/PHP5.6toPHP7.3/1.1_mcrypt%E5%AF%BE%E5%BF%9C.md
移行の結果
既存のコード
暗号化
複合化
修正コード
共通処理
暗号化
復号化
BlowfishにおけるMcryptとOpenSSLの違い
動作を確認したところ、以下のようになっていました。
暗号鍵が短い場合の処理の違い
暗号化キーが abc
だとします。
Mcrypt
16bit以上の長さになるまで循環されて拡張される。
OpenSSL
16bitの長さになるまで0で埋めて拡張される。
対策
OpenSSLの関数を呼び出す前に、こちらで暗号鍵を長くします。
暗号化されたデータの違い
暗号化する際の文字列を固定ブロック長に分割したときの動作が違うようでした。
暗号化キーが abc
だとします。
Mcrypt
固定ブロック長(1octet)のサイズになるように、NULL(ゼロ)パディングされます。
OpenSSL
PKCS#7パディングが行われます。
💡
上記の場合、 5 ビットパディングされているので \x05
になります。
対策
暗号化する前に、暗号化キーに対して固定ブロック長のNULL(ゼロ)パディングを自分で実装して適用します。
最後に
Mcrypt は既に廃止されたライブラリということもあり、既に他の言語でも OpenSSL が使われています。 今回のように Mcrypt でした暗号が全く同じ方式だったとしても、ちょっとした仕様の違いで OpenSSL で復号が出来ない場合があります。
Mcrypt で暗号化したデータを復号しなければならない案件の都合上、 Mcrypt を使い続けるか書き直すかのどちらかでしたが、今回は Mcrypt で暗号している部分が少なかった事もあり OpenSSL で書き直しました。
参考サイト様は大変参考になりました。ありがとうございました。