Передача строк в кодировке base64 в URL


Безопасно ли передавать необработанные строки в кодировке base64 с помощью параметров GET?

Author: Alix Axel, 2009-09-03

9 answers

Нет, вам нужно будет закодировать его по URL, так как строки base64 могут содержать символы "+", "=" и "/", которые могут изменить значение ваших данных - выглядеть как подпапка.

Ниже указаны допустимые символы base64.

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
 169
Author: Thiyagaraj, 2009-09-03 17:19:01

Существуют дополнительные спецификации 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, '._-', '+/='));
}
 231
Author: Joe Flynn, 2017-07-17 14:16:45

@joeshmo Или вместо написания вспомогательной функции вы могли бы просто URL-кодировать строку в кодировке base64. Это будет делать то же самое, что и ваша вспомогательная функция, но без необходимости в двух дополнительных функциях.

$str = 'Some String';

$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
 65
Author: rodrigo-silveira, 2011-12-21 18:45:24

Вступительное примечание Я склонен опубликовать несколько разъяснений, поскольку некоторые ответы здесь были немного вводящими в заблуждение (если не неправильными).

Ответ - НЕТ, вы не можете просто передать параметр в кодировке 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() ввод, однако, был бы избыточным и, следовательно, ненужным.

 38
Author: Jeffory J. Beckers, 2016-07-06 16:17:26

Да и нет.

Базовая кодировка base64 в некоторых случаях может противоречить традиционным соглашениям, используемым в URL-адресах. Но многие реализации base64 позволяют вам изменять кодировку, чтобы лучше соответствовать URL-адресам, или даже использовать ее (например, Python urlsafe_b64encode()).

Еще одна проблема, с которой вы можете столкнуться, - это ограничение длины URL-адреса или, скорее, отсутствие такого ограничения. Поскольку стандарты не определяют максимальную длину, браузеры, серверы, библиотеки и другое программное обеспечение, работающее с HTTP протокол может определять свои собственные пределы. Вы можете ознакомиться с этой статьей: Часто задаваемые вопросы WWW: Какова максимальная длина URL-адреса?

 13
Author: Michał Górny, 2009-09-03 17:20:40

Это кодировка 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));
}
 5
Author: Andy, 2015-07-21 08:31:48

Я не думаю, что это безопасно, потому что, например, символ "=" используется в необработанной базе 64, а также используется для отличия параметров от значений в HTTP GET.

 4
Author: Mischa, 2009-09-03 17:18:25

Теоретически, да, если вы не превышаете максимальную длину URL-адреса и/или строки запроса для клиента или сервера.

На практике все может быть немного сложнее. Например, он может вызвать исключение HttpRequestValidationException при ASP.NET если значение содержит "вкл", и вы оставляете в конце "==".

 1
Author: Nicole Calinoiu, 2009-09-03 17:22:52

Да, это всегда безопасно. конечно, base64 содержит: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= но строка в кодировке base64 обычно не имеет +. + будет преобразовано в пустое пространство, что приведет к неправильному декодированию строки. / безопасен в паре параметров get. = всегда находится в конце строки в кодировке base64, и серверная сторона может разрешить = напрямую.

 -4
Author: gouchaoer, 2017-02-06 09:13:32