ОБНОВЛЕНИЕ (РЕШЕНИЕ)
Поскольку эта публикация, похоже, заслуживает пристального внимания, я хотел бы сообщить вам, что в итоге было решено предоставить правильный параметр enctype
(тип контента) в объявлении <FORM>
. Вы должны установить значение multipart/form-data
, чтобы предотвратить кодирование, которое в противном случае имело бы место, используя стандартный тип application/x-www-form-urlencoded
. Небольшая выдержка из форм в документах HTML на w3.org:
Тип контента
"application / x-www-form-urlencoded" является
неэффективно для отправки больших
количество двоичных данных или текста
содержащие не-ASCII символы.
тип содержимого "multipart / form-data"
следует использовать для отправки форм
которые содержат файлы, не-ASCII данные,
и двоичные данные.
А вот правильная декларация 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
, либо serialization
снимает символы с $encrypted_data
. Может ли кто-нибудь проверить, является ли это виновником и существуют ли альтернативные методы кодирования ключей формы?