it-swarm.com.ru

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

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

213
Alix Axel

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

Допустимые символы base64 приведены ниже.

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
182
Thiyagaraj

Есть дополнительные спецификации 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, '._-', '+/='));
}
252
Joe Flynn

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

$str = 'Some String';

$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
68
rodrigo-silveira

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

Ответ НЕТ , вы не можете просто передать закодированный в 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% 2Bsign в

//test.php
$string = urldecode($_GET['myVar']);
print $string;

результат неожиданный:
stringwith sign

Было бы безопасно rawurldecode() ввод, однако, он будет избыточным и, следовательно, ненужным.

38
Jeffory J. Beckers

И да и нет.

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

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

13
Michał Górny

Это кодировка 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));
}
8
Andy

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

4
Mischa

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

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

1
Nicole Calinoiu