Безопасно ли передавать необработанные строки в кодировке base64 через параметры GET?
Передача строк в кодировке base64 в URL
Ответы (9)
Нет, вам нужно будет закодировать его URL-адресом, поскольку строки base64 могут содержать символы «+», «=» и «/», которые могут изменить значение ваших данных - выглядят как подпапка.
Ниже приведены допустимые символы base64.
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
(['
вместо {["
).
- person rinogo; 26.10.2015
Есть дополнительные спецификации 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-адреса, это все равно что войти в ваш дом, проходя через окно, а не просто использовать дверь.
- person Marco Demaio; 26.02.2014
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
- person kralyk; 30.09.2015
,
должен иметь кодировку %2C
, я предлагаю использовать ._-
вместо -_,
, как единственный вариант в en. wikipedia.org/wiki/Base64#Variants_summary_table, который сохраняет конечный =
- person PaulH; 03.07.2016
.
, который в этом случае не будет считаться частью URL-адреса некоторыми почтовыми клиентами. Тем не менее, я все же рекомендую замену, предложенную здесь, потому что некоторые почтовые клиенты оптимизируют //
на /
в URL-адресах, а также не принимают конечные =
-знаки как часть URL-адреса.
- person MaPePeR; 08.01.2019
minus
и underline
(с equals
для панели), как описывает ответ Джо Флинна.
- person ToolmakerSteve; 12.12.2020
@joeshmo Или вместо того, чтобы писать вспомогательную функцию, вы можете просто urlencode кодировать строку в кодировке base64. Это будет делать то же самое, что и ваша вспомогательная функция, но без необходимости в двух дополнительных функциях.
$str = 'Some String';
$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
/
, если вы передаете его не как параметр GET, а как путь в URL-адресе. Это изменит ваш путь, если вы не замените /
чем-то другим с обеих сторон.
- person NeverEndingQueue; 01.09.2017
url = URLEncoder.encode(Base64.getEncoder().encodeToString(value), StandardCharsets.UTF_8)
Base64.getDecoder().decode(URLDecoder.decode(code, StandardCharsets.UTF_8))
- person Grigory Kislin; 30.04.2020
+
. Подробности см. В ответе Джеффори Беккерса.
- person ToolmakerSteve; 12.12.2020
Вводное примечание Я склонен опубликовать несколько пояснений, поскольку некоторые ответы здесь были немного вводящими в заблуждение (если не неверными).
Ответ - НЕТ, вы не можете просто передать параметр в кодировке base64 в строке запроса URL, поскольку знаки плюса преобразуются в ПРОБЕЛ внутри глобального массива $ _GET. Другими словами, если вы отправили test.php? MyVar = stringwith + sign в
//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% 2B подписать на
//test.php
$string = urldecode($_GET['myVar']);
print $string;
результат неожиданный: stringwith sign
Было бы безопасно ввести rawurldecode()
ввод, однако он будет избыточным и, следовательно, ненужным.
<br>
, поэтому нет необходимости вводить много HTML. Надеюсь, это поможет, я немного отредактировал ваш ответ, чтобы еще больше улучшить его.
- person hakre; 26.09.2012
Да и нет.
Базовая кодировка base64 в некоторых случаях может противоречить традиционным соглашениям, используемым в URL-адресах. Но многие реализации base64 позволяют вам изменить кодировку для лучшего соответствия URL-адресам или даже пойти с ней (например, Python _ 1_).
Еще одна проблема, с которой вы можете столкнуться, - это ограничение длины URL или, скорее, отсутствие такого ограничения. Поскольку стандарты не определяют максимальную длину, браузеры, серверы, библиотеки и другое программное обеспечение, работающее с протоколом HTTP, могут определять свои собственные ограничения.
Это кодировка 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));
}
Base64.getUrlEncoder().withoutPadding().encodeToString()
- person ; 27.03.2019
Я не думаю, что это безопасно, потому что, например, символ «=» используется в исходной базе 64, а также используется для отличия параметров от значений в HTTP GET.
Теоретически да, если вы не превышаете максимальную длину строки запроса url и / oor для клиента или сервера.
На практике все может быть немного сложнее. Например, он может вызвать исключение HttpRequestValidationException в ASP.NET, если значение содержит «on», а вы оставите в конце «==».
Для безопасного кодирования URL, например base64.urlsafe_b64encode(...)
в Python, приведенный ниже код работает для меня на 100%
function base64UrlSafeEncode(string $input)
{
return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
}