[解決済み] php が MCRYPT_RIJNDAEL_256 で文字列を復号します。
2022-02-15 06:29:32
質問
<?php
function encrypt ($key,$iv,$str)
{
$block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding=$block-(strlen($str) % $block);
$str.=str_repeat(chr($padding), $padding);
$encryptxt=mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);
$encryptxt64=base64_encode($encryptxt);
return $encryptxt64;
}
function decrypt ($key,$iv,$str)
{
$block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding=$block-(strlen($str) % $block);
$str.=str_repeat(chr($padding), $padding);
$decryptxt=mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);
$decryptxt64=base64_decode($decryptxt);
return $decryptxt64;
}
echo encrypt("1234567890123456","12345678901234561234567890123456","test")."\n<br/>";
echo decrypt("1234567890123456","12345678901234561234567890123456","xHqKvRQ6FXehOGGMrKoek04146M2l9bv1ScP6C1qCyg=")."\n<br/>";
?>
この方法で文字列を暗号化することができ、問題なく動作しますが、文字列を復号化しようとすると、上記のコードが動作しません。 復号化出力は以下のようなものです。
� S�'=�l_25A�?
どなたか復号化部分を修正する方法をご存知ですか?
解決方法は?
コメントで述べたように、これはあなたが持っているものです。
//encrypt
$encryptxt=mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);
$encryptxt64=base64_encode($encryptxt);
//decrypt
$decryptxt=mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);
$decryptxt64=base64_decode($decryptxt);
- 暗号化
- base64エンコード
- 復号化
- base64デコード
FILO ( First in Last Out ) であるべきです。
- 暗号化
- base64エンコード
- ベース64デコード
- 復号化
そうすると、encryptの出力を復号化することになり ではなく base64でエンコードされた出力です。
Like So:
$encryptxt=mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);
$encryptxt64=base64_encode($encryptxt);
//decrypt
$decryptxt64=base64_decode($str);
$decryptxt=mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key,$decryptxt64,MCRYPT_MODE_CBC,$iv);
MCRYPT_RIJNDAEL_256 は AES 256 ではないので、MCRYPT_RIJNDAEL_128 と 32 バイトの鍵が必要です。
もうひとつ、入力文字列のmd5ハッシュをとって、それを暗号化の前に入力文字列にプリペンドすることをお勧めします。 これは、暗号化を解除するときに、最初の32文字をsubstrして、それを使って入力をチェックすることができるようにするためです。 基本的に、復号化されたかどうかを確認するためには、入力文字列を知る必要があります。 しかし、ハッシュ化し、このように比較することで、入力文字列を知る必要がなくなり、動作確認ができるようになります。
というわけで、まとめてみました(テストはしていませんが、近いものがあるはずです)。
function encrypt ($key,$iv,$str)
{
$block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding=$block-(strlen($str) % $block);
$str.=str_repeat(chr($padding), $padding);
///prepend a md5 hash of the plain text input before encrypting it ( so we can check it later )
$str = md5( $str ) . $str;
$encryptxt=mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);
$encryptxt64=base64_encode($encryptxt);
return $encryptxt64;
}
function decrypt ($key,$iv,$str)
{
$block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding=$block-(strlen($str) % $block);
$str.=str_repeat(chr($padding), $padding);
$decryptxt64=base64_decode($str);
$decryptxt=mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key,$decryptxt64,MCRYPT_MODE_CBC,$iv);
///Separate the md5 hash from the other text, and then hash the other text and compare to the hash we included when encrypting if they are = it all worked.
/// it is perfectly safe to use md5 here because it will be part of what we encrypt, and not accessible until it is decrypted.
///it's sole purpose is to give us 2 things we can compare to check that the decryption worked
$hash = substr( $decryptxt, 0, 32); //find first 32 characters (md5 output is always 32 characters long )
$decryptxt = substr($decryptxt, 33); //find everything after the fist 32
if( $hash != md5($decryptxt) ){
die( 'fail' ); /// or some other error
}
return $decryptxt64;
}
関連
-
[解決済み】Weird PHP error: 'Can't use function return value in write context'.
-
[解決済み] * vchiqインスタンスを開くのに失敗しました。
-
[解決済み】phpのシンタックスエラー、予期しないT_IFエラーを修正する方法は?[クローズド]。
-
[解決済み] PHPで配列から要素を削除する
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] ある文字列が特定の単語を含んでいるかどうかを確認するにはどうすればよいですか?
-
[解決済み] PHPでHTML/XMLをパースして処理する方法とは?
-
[解決済み] PHPのstartWith()関数とendsWith()関数
-
[解決済み】PHPの'foreach'は実際どのように動作するのですか?
-
[解決済み] リファレンス - このシンボルはPHPで何を意味するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】PHP - 構文エラー、予期しないT_CONSTANT_ECAPSED_STRING [閉店].
-
[解決済み】XAMPPポート80をPID 4の「Unable to open process」が使用中 [重複] XAMPPポート80をPID 4の「Unable to open process」が使用中。]
-
[解決済み】phpのob_start()の使い道は?
-
[解決済み] 整形されていない数値が発生しました。
-
[解決済み】mysqli_result クラスのオブジェクトを文字列に変換できない
-
[解決済み】「セッションキャッシュリミッターを送信できません - ヘッダーはすでに送信されています」【重複】。
-
[解決済み] SAJAXは死んだか?何を置き換えるべきか?
-
[解決済み] SQLSTATE[HY093]: 無効なパラメータ番号: バインドされた変数の数が102行目のトークンの数と一致しない [終了]
-
[解決済み] PHP と mod_fcgid: handle_request_ipc 関数で ap_pass_brigade が失敗する。
-
[解決済み] SSLエラー SSL3_GET_SERVER_CERTIFICATE:証明書の検証に失敗しました。