この記事では、PHP7.1 の mcrypt を openssl で置き換える具体的な例を中心に紹介しています。非常に詳しく紹介していますので、必要な方は参考にしてください。
PHP 開発では、mcrypt 関連を使用します。関数 AES 暗号化および復号化操作は簡単に実行できますが、mcrypt 拡張機能は PHP7.1 で廃止されたため、別の実装を見つける必要があります。 mcrypt を openssl に置き換えることは移行マニュアルですでに指摘されていますが、具体的な例は示されていません。ほとんどのシナリオを置き換えることができる例がオンラインに多数ありますが、詳細は説明されていません。同様に、オンラインのサンプルを使用するだけでは、特定のコード シナリオでのコード置換の前後で互換性の問題が発生する可能性があります。具体的なコードとその理由については、以下で説明します。
まず、置換コードを直接与えてから、コードから問題を分析します。 (この記事で分析するアルゴリズムは AES-128-CBC です)
置換例
この例では、mcrypt を使用する 2 つの方法を示します。違いは主にパディングにあります (パディングについては後で説明します)。暗号化と復号化のプロセス全体で、より完全なコードは埋め込みと埋め込みの削除を自動的に実装し、より単純なコードは埋め込みを直接無視しますが、どちらの方法も正常に実行できます。実際の開発 (7.1 より前のバージョン) では、これをお勧めします。パディングを追加します。次の具体的な例を参照してください:
mcrypt はパディングを使用しません
mcrypt 暗号化:
$key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $iv = 'aaaaaaaaaaaaaaaa'; $data = 'dataString'; $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); mcrypt_generic_init($cipher, $key, $iv); $cipherText256 = mcrypt_generic($cipher, $data); mcrypt_generic_deinit($cipher); return bin2hex($cipherText256);
同じ関数の OpenSSL 暗号化コード:
$key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $iv = 'aaaaaaaaaaaaaaaa'; $data = 'dataString';
$data = $data . str_repeat("\x00", 16 - (strlen($data) % 16)); // 双引号可以解析asc-ii码\x00 return bin2hex(openssl_encrypt($data, "AES-256-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv));
mcrypt はパディングを使用します
mcrypt 暗号化:
$key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $iv = 'aaaaaaaaaaaaaaaa'; $data = 'dataString'; // 填充(移除填充反着移除即可) $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $pad = $block - (strlen($data) % $block); if ($pad <= $block) { $char = chr($pad); $data .= str_repeat($char, $pad); } $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); mcrypt_generic_init($cipher, $key, $iv); $cipherText256 = mcrypt_generic($cipher, $data); mcrypt_generic_deinit($cipher); return bin2hex($cipherText256);
同じ機能を持つ openssl 暗号化コード:
$key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $iv = 'aaaaaaaaaaaaaaaa'; $data = 'dataString'; return bin2hex(openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv));
上記の例はすべて正常に実行されます。最初の例 (パディングなし、openssl ではパディングあり) と 2 番目の例 (パディングあり、openssl ではパディングなし) は置換前後で同じ出力を持ちます。互換性の問題。コードのさまざまな充填方法に基づいて、さまざまな置換ソリューションを選択できますが、説明する必要がある 3 つの詳細があります。
なぜ充填するのか?
openssl に置き換えた後、アルゴリズムの名前が異なるのはなぜですか?
次の章では、充填とアルゴリズムを詳細に分析します。
パディング
パディングが存在する理由は、暗号化アルゴリズムから始まります。 AES-128-CBC アルゴリズムでは、暗号化される文字列が長さ 16 バイトごとのセグメントに分割され、段階的に計算されるため、16 バイト未満のセグメントが埋められることになります。したがって、2 種類の例が示されています。1 つはデフォルトの塗りつぶしを使用するもので、もう 1 つは独立した塗りつぶしを使用するものです。 openssl への置き換えでは、パディング スキームを選択する方法には、mcrypt と openssl のデフォルトおよび自律的なパディングを理解する必要があります。
mcrypt のデフォルトの埋め込み
php のソース コードでは、デフォルトの埋め込みが \x00 であることがわかりますが、実際には \ で埋められていません。 x00. から 16ビットの空文字列が最初に適用されていることがソースコードに見られますので、初期化時に各バイトが\x00となっています。実際にはパディングが無いとも言えますが、本来は\ですx00、およびデフォルトのパディングを使用して取得された暗号化。文字列は次の形式になります。
#mcrypt には ## が入ります。デフォルトでは
# なので、復号化するときに冗長な \ を削除する必要があります。もちろん、怠けて \x00 を削除しないこともできます。 php では文字列 "string\x00" と文字列 "string" は長さ以外は同じ性能なので違いはないようです 以下のコード:// 尾部包含若干个`\x00` 均可功输出true if ("string\x00" == "string") { // 用双引号可解析\x00 echo true; }
mcryptAutonomous fill
充填アルゴリズムは次のアルゴリズムに従って実行する必要があります:充填の追加
/** * 填充算法 * @param string $source * @return string */ function addPKCS7Padding($source) { $source = trim($source); $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $pad = $block - (strlen($source) % $block); if ($pad <= $block) { $char = chr($pad); $source .= str_repeat($char, $pad); } return $source; }
/** * 移去填充算法 * @param string $source * @return string */ function stripPKSC7Padding($source) { $source = trim($source); $char = substr($source, -1); $num = ord($char); if ($num == 62) return $source; $source = substr($source, 0, -$num); return $source; }
openssl デフォルトの充填
デフォルトの方法は、標準の mcrypt に依存しない充填方法と一致しているため、2 番目の例では、上記の充填アルゴリズムを使用した後、 openssl_encrypt は直接使用できます。置き換えによって互換性の問題が発生することはありません。パディングされた暗号化文字列は次の形式になります。 パディングとパディングの削除は openssl_encrypt と openssl_decrypt に組み込まれているため、そうでない限り直接使用できることに注意してください。パディングを実装します。それ以外の場合はパディングを考慮する必要はありませんopenssl 自律パディング
openssl_encrypt は自律パディングをサポートするオプション パラメーターを提供しますただし、openssl の php ソース コードを調べた結果、テスト ケース コードでは正しい使用法が見つかりました:// if we want to manage our own padding $padded_data = $data . str_repeat(' ', 16 - (strlen($data) % 16)); $encrypted = openssl_encrypt($padded_data, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv); $output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv); var_dump(rtrim($output)); (备注:如上,OPENSSL_ZERO_PADDING 并非是为0填充的意思)
これから、最初の例で openssl_encrypt の前に独立ポイント課金 \x00 のコードが追加された理由が説明できます。
上記の暗号化と復号化では、充填ロジックが異なります。上記の例はよく説明できます:
例 1:
mcrypt は暗号化時にパディングを使用しないため、\x00 でパディングされます。そのため、openssl に置き換える場合は、次のように実装する必要があります。 \x00 を独立してパディングします。
例 2:
mcrypt は暗号化時に標準パディングを使用します。openssl のパディング メソッドも標準パディングであるため、それを直接使用できます。
これを分析した結果、パディング戦略がどのようなものであっても、暗号化中にパディングを追加し、復号化中にパディングを削除することに注意を払う必要があることがわかります。これで上記例の充填関連の解析は完了しましたので、次に置き換えるアルゴリズムの選び方を見ていきます。
アルゴリズムの選択
上記の例では、mcrypt の AES-128-CBC アルゴリズムが openssl で使用されていないという問題があります。 AES_256に置き換えるにはどうすればいいですか?
この点に関しては、適当な説明が見つからず、ソースコードを少し調べてみましたが原因が分かりませんでした(能力には限界があります~)が、以下の方法で解決しました。情報、関数はまだ完了していました
openssl mcrypt AES データの非互換性の問題を復号化します
mcrypt_generic を openssl_encrypt に変換します質問をする
学生が理由を見つけた場合、メッセージを残してください、ありがとうございます。
概要
mcrypt AES を使用した暗号化部分については、置き換えプロセス中に問題が発生した場合は、アルゴリズムからの 2 つについて考えてみましょう。同時に満たさなければならない条件の一つは、充填方法の違いに応じて選択することですが、交換時に最も重要なことは、交換後に変化が起こらないことを確認することです。最後の数文字列の違いというわずかな違いしかありませんが、複数のプラットフォームで同時に変更するのは面倒ですが、変更が少ないほどリスクは小さくなります。
この記事では AES アルゴリズムについて簡単に説明するだけであり、他のアルゴリズムが適用できるかどうかは検討の余地があります。
上記がこの記事の全内容です。皆様の学習に少しでもお役に立てれば幸いです。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。
関連する推奨事項:
Canvas イメージを HTML5 でサーバーに保存する PHP 実装
PHP インターフェイスの多重継承とタリット多重継承エフェクトの実装方法_php スキル
Laravel フレームワーク Blob で実装された複数画像アップロード機能の分析例
#
以上がPHP7.1 で openssl を使用して mcrypt を置き換える方法の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。