Передача строк в кодировке base64 в URL
Безопасно ли передавать необработанные строки в кодировке base64 с помощью параметров GET?
9 answers
Нет, вам нужно будет закодировать его по 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, '._-', '+/='));
}
@joeshmo Или вместо написания вспомогательной функции вы могли бы просто URL-кодировать строку в кодировке base64. Это будет делать то же самое, что и ваша вспомогательная функция, но без необходимости в двух дополнительных функциях.
$str = 'Some String';
$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
Вступительное примечание Я склонен опубликовать несколько разъяснений, поскольку некоторые ответы здесь были немного вводящими в заблуждение (если не неправильными).
Ответ - НЕТ, вы не можете просто передать параметр в кодировке base64 в строке запроса URL, поскольку знаки плюс преобразуются в ПРОБЕЛ внутри глобального массива $_GET. Другими словами, если вы отправили test.php?myVar=строку со знаком+ в
//test.php
print $_GET['myVar'];
Результат был бы быть:stringwith sign
Простой способ решить эту проблему - просто urlencode()
ваша строка base64 перед добавлением ее в строку запроса, чтобы избежать символов +, = и / в кодах %##.
Например, urlencode("stringwith+sign")
возвращает stringwith%2Bsign
Когда вы обрабатываете действие, PHP автоматически расшифровывает строку запроса, когда она заполняет $_GET global. Например, если я отправил test.php?myVar=строку с %2bsign в
//test.php
print $_GET['myVar'];
Результатом будет:stringwith+sign
Ты делаешь не хотите urldecode()
возвращенная строка $_GET в виде + будет преобразована в пробелы.
Другими словами, если бы я отправил тот же test.php?myVar=строку с %2bsign в
//test.php
$string = urldecode($_GET['myVar']);
print $string;
Результат неожиданный:stringwith sign
Было бы безопасно rawurldecode()
ввод, однако, был бы избыточным и, следовательно, ненужным.
Да и нет.
Базовая кодировка 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));
}
Я не думаю, что это безопасно, потому что, например, символ "=" используется в необработанной базе 64, а также используется для отличия параметров от значений в HTTP GET.
Теоретически, да, если вы не превышаете максимальную длину URL-адреса и/или строки запроса для клиента или сервера.
На практике все может быть немного сложнее. Например, он может вызвать исключение HttpRequestValidationException при ASP.NET если значение содержит "вкл", и вы оставляете в конце "==".
Да, это всегда безопасно.
конечно, base64 содержит:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
но строка в кодировке base64 обычно не имеет +
. +
будет преобразовано в пустое пространство, что приведет к неправильному декодированию строки. /
безопасен в паре параметров get. =
всегда находится в конце строки в кодировке base64, и серверная сторона может разрешить =
напрямую.