PHP:ごみに文字列のmcryptのマングル始まり
-
19-09-2019 - |
質問
私は、サーバー側での強力な暗号化にメディアを必要とするので、私は、私はPHPでmcryptの使用だろうと思いました。私は私の元の文字列の先頭の下の関数を使用している場合、復号後のバイナリごみに変わります。 (これはの追加のごみ、代わりに私の文字列は、のの変更された追加取得の通常の問題ではありません。)のドキュメントによると、MCRYPT_ENCRYPT()と一致するように十分な文字を埋めている必要がありますブロック選択アルゴリズムの大きさが、私はそれが動作しないと思います。
しかし、私はパッドが手動でラインダールの128ビット(16バイト)のブロックサイズに、それはどちらか動作しない場合。私は仕事にこれを取得することができる唯一の方法は、(おそらく)に十分な長さ、いくつかの文字列を付加することである化けブロックをカバーし、その文字列と私のデータ間の「データ#」のような知られている接頭辞を追加します。ブロックが部分的にマングルされてきましたが、その後、私の接頭辞とすべてのデータが正しく復号されています。
復号化した後、$GLOBALS['encryptionmarker'] = 'DATA#';
function encrypt($plain, $key) {
/*
// workaround because beginning of decrypted string is being mangled
// so we simply prefix with some text plus marker
$prefix = str_pad('', 128, '#', STR_PAD_RIGHT).$GLOBALS['encryptionmarker'];
$plain = $prefix.$plain;
*/
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $plain, MCRYPT_MODE_CFB,
mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
MCRYPT_DEV_URANDOM));
return $encrypted;
}
function decrypt($encrypted, $key) {
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CFB,
mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
MCRYPT_DEV_URANDOM));
/*
// workaround: remove garbage
$pos = strpos($decrypted, $GLOBALS['encryptionmarker']);
$decrypted = trim(substr($decrypted, $pos + strlen($GLOBALS['encryptionmarker'])));
*/
return $decrypted;
}
何が私の機能が悪いですの?なぜ私は(私はそれ汚い回避策を検討し、私はそれを修正したいと思います)そのように私のデータの前に付ける必要はありますか?
は暗号化されたデータを格納することは問題ではありません。同じエラーでデータベースの結果にそれを格納することなく、暗号化した直後に、それを解読ます。
解決
あなたの問題は、受信側の新しい、異なる、ランダムなIVを生成しているということです。あなたが見てきたように、これは、動作しません。
受信機は、送信者が使用するIVを知っている必要があります。あなたが暗号化されたデータと、それに沿って送信し、mcrypt_decrypt()
するためにそれを渡す必要があります。
あなたはまた、メッセージの上にHMACを生成し、受信側でそれを確認するために、キー(暗号化キーに異なるキー)でmhash()
を使用しなければならないことに注意してください。そうしない場合は、のman-in-the-middleは自明あなたがそれを検出せずに、あなたのメッセージの一部を変更することができます。
他のヒント
エン化と復号に同じIVを使用してください。 IVは、共有秘密ではなく、共有することがあります。あなたはウィキペディアを調べることができる:IV の
$IV = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
MCRYPT_DEV_URANDOM));
IVはONCE転送する必要があります。あなたは、各パケットのためにIVの値をインクリメントすることをお勧めします。しかし、これは独立して、両側に行うことができます。