ZeroPadding

Принцип дополнения блоков данных

Блочные алгоритмы шифрования (AES, DES и другие) работают с фиксированными размерами блоков, чаще всего 16 байт для AES. Если входные данные не кратны размеру блока, требуется механизм дополнения (padding), который доводит длину сообщения до необходимого значения.

ZeroPadding — один из простейших методов дополнения, при котором недостающие байты заполняются нулевыми значениями (0x00).


Механизм работы ZeroPadding

При использовании ZeroPadding:

  • вычисляется остаток от деления длины данных на размер блока
  • если остаток равен нулю, дополнение не добавляется
  • если остаток присутствует, добавляется необходимое количество байтов со значением 0x00

Формально:

padding_length = block_size - (data_length % block_size)

Если padding_length != 0, то:

data += [0x00, 0x00, ... padding_length раз]

Особенности представления данных

ZeroPadding не содержит метаданных о длине исходного сообщения. Это создаёт принципиальную особенность:

  • невозможно отличить реальные нулевые байты в конце данных от добавленного padding
  • восстановление исходного сообщения требует внешнего знания длины данных

Это ключевое отличие от более сложных схем дополнения.


Использование ZeroPadding в CryptoJS

В библиотеке CryptoJS padding задаётся через объект CryptoJS.pad.

Пример применения ZeroPadding при шифровании AES:

const CryptoJS = require("crypto-js");

const message = "Hello CryptoJS";
const key = CryptoJS.enc.Utf8.parse("1234567890123456");

const encrypted = CryptoJS.AES.encrypt(message, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.ZeroPadding
});

const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.ZeroPadding
});

const result = decrypted.toString(CryptoJS.enc.Utf8);

Реализация ZeroPadding в CryptoJS

Внутренняя реализация основана на добавлении нулевых байтов до размера блока:

CryptoJS.pad.ZeroPadding = {
    pad: function (data, blockSize) {
        const blockSizeBytes = blockSize * 4;

        const dataSigBytes = data.sigBytes;
        const paddingBytes = blockSizeBytes - (dataSigBytes % blockSizeBytes);

        for (let i = 0; i < paddingBytes; i++) {
            data.concat(CryptoJS.lib.WordArray.create([0x00000000], 1));
        }
    },

    unpad: function (data) {
        const sigBytes = data.sigBytes;

        let i = sigBytes - 1;

        while (i >= 0 && data.words[i >>> 2] & (0xff << (24 - (i % 4) * 8)) === 0) {
            i--;
        }

        data.sigBytes = i + 1;
    }
};

Отличие ZeroPadding от PKCS7

Основное различие заключается в способе кодирования длины padding:

ZeroPadding

  • заполняет байтами 0x00
  • не хранит информацию о размере padding
  • неоднозначен при наличии нулей в данных

PKCS7 Padding

  • каждый добавленный байт равен количеству добавленных байтов
  • всегда можно однозначно восстановить исходные данные

Пример PKCS7:

... | 05 05 05 05 05

Проблема неоднозначности данных

Если исходное сообщение заканчивается на нулевые байты, возникает неоднозначность:

  • невозможно определить, где данные, а где padding
  • при декодировании возможно удаление значимых байтов

Пример:

Исходные данные:  "ABCD\0\0"
После padding:    "ABCD\0\0\0\0\0\0"

После расшифровки невозможно понять реальную длину исходного сообщения без внешнего контекста.


Сценарии применения

ZeroPadding встречается в следующих случаях:

  • устаревшие протоколы, где фиксирован формат сообщений
  • бинарные структуры с заранее известной длиной
  • системы, где данные не содержат нулевых байтов в конце
  • совместимость с аппаратными реализациями шифрования

Влияние на безопасность

Сам по себе ZeroPadding не является криптографической уязвимостью, однако:

  • повышает риск ошибок обработки данных
  • может привести к некорректному восстановлению информации
  • требует строгого контроля формата входных сообщений

Современные системы чаще используют PKCS7 как стандарт по умолчанию.


Взаимодействие с режимами шифрования

Padding применяется только в блочных режимах, где требуется выравнивание:

  • ECB
  • CBC

В потоковых режимах (CFB, OFB, CTR) padding не используется, так как данные шифруются побайтно или с генерацией потока ключа.


Обработка бинарных данных

При работе с бинарными данными ZeroPadding становится особенно проблемным:

  • нулевые байты являются допустимой частью данных
  • невозможна корректная дифференциация padding и полезной нагрузки
  • требуется внешняя схема определения длины

Практическое сравнение поведения

При одинаковом входе различия в результате:

  • ZeroPadding: дополняет нулями до блока
  • PKCS7: дополняет значениями, равными длине padding

Это влияет на итоговую расшифровку при наличии нулевых байтов в данных.


Совместимость между реализациями

При взаимодействии разных криптографических библиотек важно учитывать:

  • не все реализации поддерживают ZeroPadding
  • возможны расхождения в удалении padding
  • требуется явное согласование схемы дополнения между сторонами обмена данными