Безопасно ли передавать строки в кодировке base64 через параметры GET?
Безопасно ли передавать строки в кодировке base64 через параметры GET?
Ответы:
Нет, вам нужно будет его кодировать по URL-адресу, поскольку строки base64 могут содержать символы «+», «=» и «/», которые могут изменить значение ваших данных - они выглядят как подпапка.
Допустимые символы base64 приведены ниже.
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
Есть дополнительные спецификации base64. (Смотрите таблицу здесь для уточнения). Но по сути вам нужно 65 символов для кодирования: 26 строчных + 26 прописных + 10 цифр = 62.
Вам нужно еще два ['+', '/'] и дополнительный символ '='. Но ни один из них не является дружественным к URL, поэтому просто используйте разные символы для них, и все готово. Стандартными из приведенного выше графика являются ['-', '_'], но вы можете использовать другие символы, если вы расшифровали их одинаково, и вам не нужно делиться с другими.
Я бы порекомендовал просто написать своих собственных помощников. Как это из комментариев на странице руководства php для base64_encode :
function base64_url_encode($input) {
return strtr(base64_encode($input), '+/=', '._-');
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '._-', '+/='));
}
urlencode
что предложено ответом Родриго-Силвейры. Создание двух новых функций для сохранения нескольких символов в длине URL, это все равно что войти в свой дом, проходя через окно, а не просто используя дверь.
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
,
должен быть urlencoded к %2C
, я предлагаю использовать ._-
вместо -_,
единственного варианта в en.wikipedia.org/wiki/Base64#Variants_summary_table, который сохраняет трейлинг =
@joeshmo Или вместо написания вспомогательной функции, вы можете просто urlencode строки в кодировке base64. Это будет делать то же самое, что и ваша вспомогательная функция, но без необходимости использования двух дополнительных функций.
$str = 'Some String';
$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
/
символом, если вы передаете его не как параметр GET, а как путь в URL. Это изменит ваш путь, если вы не замените /
что-то еще с обеих сторон.
Вводное примечание Я склонен опубликовать несколько разъяснений, поскольку некоторые ответы здесь немного вводят в заблуждение (если не неверно).
Ответ НЕТ , вы не можете просто передать закодированный в base64 параметр в строке запроса URL, поскольку знаки плюс преобразуются в ПРОБЕЛ в глобальном массиве $ _GET. Другими словами, если вы отправили test.php? MyVar = stringwith + sign to
//test.php
print $_GET['myVar'];
результат будет:
stringwith sign
Самый простой способ решить эту проблему - просто urlencode()
добавить строку base64 перед добавлением ее в строку запроса, чтобы экранировать символы +, = и / в кодах% ##. Например, urlencode("stringwith+sign")
возвращаетstringwith%2Bsign
Когда вы обрабатываете действие, PHP автоматически расшифровывает строку запроса, когда она заполняет глобальную переменную $ _GET. Например, если я отправил test.php? MyVar = stringwith% 2Bsign в
//test.php
print $_GET['myVar'];
результат будет:
stringwith+sign
Вы не хотите urldecode()
возвращать строку $ _GET, так как + будут преобразованы в пробелы.
Другими словами, если я отправил тот же test.php? MyVar = stringwith% 2Bsign в
//test.php
$string = urldecode($_GET['myVar']);
print $string;
результат неожиданный:
stringwith sign
Это было бы безопасно для rawurldecode()
ввода, однако, это было бы излишним и, следовательно, ненужным.
<br>
, поэтому не нужно вводить много HTML. Надеюсь, это поможет, я немного отредактировал ваш ответ, чтобы еще лучше его улучшить.
Да и нет.
Базовый набор символов base64 может в некоторых случаях вступать в противоречие с традиционными соглашениями, используемыми в URL. Но многие реализации base64 позволяют изменить кодировку, чтобы она лучше соответствовала URL-адресам, или даже поставляются с ней (например, в Python urlsafe_b64encode()
).
Другая проблема, с которой вы можете столкнуться, - это ограничение длины URL или, скорее, отсутствие такого ограничения. Поскольку в стандартах не указана максимальная длина, браузеры, серверы, библиотеки и другое программное обеспечение, работающее по протоколу HTTP, могут определять свои собственные ограничения. Вы можете взглянуть на эту статью: Часто задаваемые вопросы WWW: Какова максимальная длина URL?
Это кодировка base64url, которую вы можете попробовать, это просто расширение кода Joeshmo, описанного выше.
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
Теоретически, да, если вы не превышаете максимальную длину URL-адреса и / или строки запроса для клиента или сервера.
На практике все может стать немного сложнее. Например, он может вызвать исключение HttpRequestValidationException в ASP.NET, если значение содержит «on» и вы оставляете в конце «==».
Для безопасного URL-кодирования, как base64.urlsafe_b64encode(...)
в Python код ниже, работает для меня на 100%
function base64UrlSafeEncode(string $input)
{
return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
}
Да, это всегда безопасно. конечно base64 содержит:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
но строка в кодировке base64 обычно не имеет +
. +
будет преобразован в пустое пространство, что приведет к неправильной декодированной строке. /
безопасен в паре параметров получения. =
всегда находится в конце строки, закодированной в base64, и серверная сторона может разрешить =
напрямую.