Возможно ли получить коллизии с base64 Encoding / Decoding - PullRequest
0 голосов
/ 09 ноября 2018

Подобный вопрос был задан здесь: Всегда ли base64 кодирует всегда один к одному

И, очевидно, ответ (на аналогичный вопрос) - ДА.Я уже знаю это, НО мне было бы любопытно узнать объяснение, почему эти две строки выглядят эквивалентными после декодирования Base64:

cwB0AGQAAG ==

cwB0AGQAAA ==


Еще одна вещь ... когда вы выбираете декодированную строку, а затем перекодируете, оба перекодируют в одно и то же значение: cwB0AGQAAA ==

Что случилось?

1 Ответ

0 голосов
/ 09 ноября 2018

base64 не один-к-одному; Есть несколько способов кодировать одни и те же байты. То, что вы видите, - это несколько способов кодирования отступа в конце строки.

base64 кодирует байты (8 бит каждый) в базу 64. Символ в базе 64 кодирует 6 бит, поэтому каждые три символа могут обрабатывать 3 байта. Когда длина ввода не кратна трем, base64 использует = в качестве символа заполнения. XXX= указывает, что должны использоваться только первые два байта группы (где XXX представляет три произвольных символа base64), тогда как XX== указывает, что должен использоваться только первый байт.

Последняя группа в вашем примере - AA==, которая кодирует 0 байт. Тем не менее, часть AA может кодировать 12 битов, из которых наименее значимые четыре игнорируются при декодировании, поэтому вы можете использовать любой символ из A-P и получить тот же результат. Когда вы используете кодировщик, он всегда выбирает нули для этих четырех битов, поэтому вы получаете обратно AA==.

Заполнение на самом деле еще более сложно в base64. Технически вы можете исключить символы =; длина строки будет указывать на их отсутствие (согласно Википедии, не все декодеры поддерживают это). Полезность padding заключается в том, что она позволяет безопасно объединять строки base64, поскольку каждая группа из четырех интерпретируется одинаково. Однако это означает, что заполнение также может появляться в середине строки, а это означает, что последовательность байтов может быть закодирована различными способами. Вы также можете включить пробелы или символы новой строки, которые все игнорируются.

Несмотря на все это, base64 все еще инъективен, то есть если x! = Y, то base64 (x)! = Base64 (y); В результате вы не можете получить коллизии и всегда можете получить исходные данные. Однако base64 не является сюръективным: существует множество способов кодирования одних и тех же данных.

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