Какие замены символов следует выполнить, чтобы сделать URL-адрес в кодировке base 64 безопасным?

#php #encryption #mcrypt

#php #perl #url #кодирование #base64

Вопрос:

Рассматривая кодировку URL safe base 64, я обнаружил, что это очень нестандартная вещь. Несмотря на большое количество встроенных функций, которые есть в PHP, нет ни одной для URL-адреса в кодировке base 64. На странице руководства для base64_encode() большинство комментариев предлагают использовать эту функцию, обернутую strtr() :

 function base64_url_encode($input)
{
     return strtr(base64_encode($input), ' /=', '-_,');
}
  

Единственным модулем Perl, который я смог найти в этой области, является MIME::Base64::URLSafe (исходный код), который выполняет следующую замену внутри:

 sub encode ($) {
    my $data = encode_base64($_[0], '');
    $data =~ tr| /=|-_|d;
    return $data;
}
  

В отличие от функции PHP выше, эта версия Perl полностью удаляет символ ‘=’ (равно), а не заменяет его на ‘,’ (запятая), как это делает PHP. Equals — это символ заполнения, поэтому модуль Perl заменяет их по мере необходимости при декодировании, но это различие делает две реализации несовместимыми.

Наконец, функция Python urlsafe_b64encode (s) сохраняет заполнение ‘=’, побуждая кого-либо использовать эту функцию для удаления заполнения, которое заметно отображается в результатах Google для «URL-адрес python base64 безопасен»:

 from base64 import urlsafe_b64encode, urlsafe_b64decode

def uri_b64encode(s):
    return urlsafe_b64encode(s).strip('=')

def uri_b64decode(s):
    return urlsafe_b64decode(s   '=' * (4 - len(s) % 4))
  

Здесь желательно иметь строку, которая может быть включена в URL-адрес без дальнейшего кодирования, отсюда удаление или перевод символов ‘ ‘, ‘/’ и ‘=’. Поскольку определенного стандарта не существует, каков правильный способ?

Ответ №1:

Похоже, существует стандарт, это RFC 3548, раздел 4, кодировка Base 64 с безопасным алфавитом URL и имени файла:

Эта кодировка технически идентична предыдущей, за исключением символов алфавита 62:nd и 63:rd, как указано в таблице 2.

и / следует заменить на - (minus) и _ (understrike) соответственно. Любые несовместимые библиотеки должны быть обернуты так, чтобы они соответствовали RFC 3548.

Обратите внимание, что для этого требуется, чтобы вы кодировали (pad) = символы в URL, но я предпочитаю, чтобы URL кодировал символы и / из стандартного алфавита base64.

Ответ №2:

Я не думаю, что это правильно или неправильно. Но самая популярная кодировка

 ' /=' => '-_.'
  

Это широко используется Google, Yahoo (они называют это Y64). Самая безопасная для URL версия кодировщиков, которые я использовал на Java, Ruby поддерживает этот набор символов.

Комментарии:

1. 1 за упоминание Y64 и добавление некоторой культуры к вопросу

Ответ №3:

Я бы предложил запустить вывод base64_encode через urlencode. Например:

 function base64_encode_url( $str )
{
    return urlencode( base64_encode( $str ) );
}
  

Ответ №4:

Если вы спрашиваете о правильном способе, я бы выбрал правильную кодировку URL-адреса, а не произвольную замену символов. Сначала base64-закодируйте ваши данные, затем дополнительно закодируйте специальные символы, такие как «=», с правильной кодировкой URL (т. Е. %<code> ).

Комментарии:

1. Я не согласен с использованием уже доступных функций, но использование urlencode() может добавить много дополнительной длины.

Ответ №5:

Почему бы вам не попробовать обернуть его в urlencode() ? Документация здесь.

Комментарии:

1. Это использует ненужное количество символов. Почему бы просто не urlencode двоичную строку в первую очередь?