更新 (解決策)
この投稿はかなりの注目を集めているように思われるので、解決策は宣言で適切なenctype
(コンテンツ タイプ) パラメーターを提供することになったことをお知らせしたいと思います。デフォルトの enctype を使用して行われるエンコードを防止するに<FORM>
は、値を に設定する必要があります。w3.orgのForms in HTML Documentsからの抜粋:multipart/form-data
application/x-www-form-urlencoded
コンテンツ タイプ「application/x-www-form-urlencoded」は、非 ASCII 文字を含む大量のバイナリ データまたはテキストを送信するのに非効率的です。ファイル、非 ASCII データ、およびバイナリ データを含むフォームを送信するには、コンテンツ タイプ「multipart/form-data」を使用する必要があります。
そして、ここに適切な FORM 宣言があります:
<FORM method="POST" action="/path/to/file/" name="encryptedForm" enctype="multipart/form-data">
最初の質問
私は、フォーム フィールド名を mcrypt を使用して暗号化された値に本質的に置き換えるフォーム スパム保護クラスに取り組んでいます。これに関する問題は、mcrypt 暗号化がフォーム フィールドを無効にする英数字だけに限定されないことです。 以下のコードを考えると、既に暗号化された配列の値を復号化する際に問題が発生する理由を思いつきますか?
/**
* Two way encryption function to encrypt/decrypt keys with
* the DES encryption algorithm.
*/
public static function encryption($text, $encrypt = true)
{
$encrypted_data = '';
$td = mcrypt_module_open('des', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
if (mcrypt_generic_init($td, substr(self::$randomizer, 16, 8), $iv) != -1) {
if ($encrypt) {
// attempt to sanitize encryption for use as a form element name
$encrypted_data = mcrypt_generic($td, $text);
$encrypted_data = base64_encode($encrypted_data);
$encrypted_data = 'i' . strtr($encrypted_data, '+/=', '-_.');
self::$encrypted[] = $encrypted_data;
} else {
// reverse form element name sanitization and decrypt
$text = substr($text, 1);
$text = strtr($text, '-_.', '+/=');
$text = base64_decode($text);
$encrypted_data = mdecrypt_generic($td, $text);
}
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
return $encrypted_data;
}
後で、次を使用して非表示のフォーム要素の値を設定する呼び出しを行います。
base64_encode(serialize(self::$encrypted))
基本的に隠しフィールドには、暗号化された値で暗号化されたすべてのフォーム フィールドの配列が含まれます。これは、バックエンドでどのフィールドを復号化する必要があるかを知るためです。フォームの送信時に、このフィールドはバックエンドで次のコードを使用して解析されます。
// load the mapping entry
$encrypted_fields = $input->post('encrypted', '');
if (empty($encrypted_fields)) {
throw new AppException('The encrypted form field was empty.');
}
// decompress array of encrypted fields
$encrypted_fields = @unserialize(base64_decode($encrypted_fields));
if ($encrypted_fields === false) {
throw new AppException('The encrypted form field was not valid.');
}
// get the mapping of encrypted keys to key
$data = array();
foreach ($_POST as $key => $val) {
// if the key is encrypted, add to data array decrypted
if (in_array($key, $encrypted_fields)) {
$decrypted = self::encryption($key, false);
$data[$decrypted] = $val;
unset($_POST[$key]);
} else {
$data[$key] = $val;
}
}
// merge $_POST array with decrypted key array
$_POST += $data;
暗号化されたフォーム フィールド キーを復号化しようとすると失敗します。$_POST
配列に新しい文字化けしたキーを作成するだけです。私の推測では、base64_encoding
orserialization
が から文字を削除してい$encrypted_data
ます。 これが原因であるかどうか、およびフォーム キーをエンコードするための代替方法があるかどうかを誰かが確認できますか?