Какие замены символов следует выполнить, чтобы сделать URL-кодировку base 64 безопасной? - PullRequest
6 голосов
/ 11 сентября 2009

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

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

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

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

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

Наконец, функция Python urlsafe_b64encode (s) поддерживает заполнение '=', предлагая кому-нибудь добавить эту функцию , чтобы удалить заполнение, которое заметно в результатах Google для 'python base64 url ​​safe' :

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 без дополнительной кодировки, отсюда исключение или перевод символов '+', '/' и '='. Поскольку не существует определенного стандарта, что является правильным?

Ответы [ 5 ]

9 голосов
/ 11 сентября 2009

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

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

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

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

8 голосов
/ 11 сентября 2009

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

'+/=' => '-_.'

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

2 голосов
/ 11 сентября 2009

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

function base64_encode_url( $str )
{
    return urlencode( base64_encode( $str ) );
}
1 голос
/ 11 сентября 2009

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

0 голосов
/ 11 сентября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...