Реализация алгоритма шифрования AES на Python
Алгоритм AES (Advanced Encryption Standard) является одним из наиболее распространённых и надёжных методов симметричного шифрования данных. Он широко используется в различных приложениях и протоколах для обеспечения конфиденциальности информации. Благодаря высокой скорости и устойчивости к криптоанализу, AES стал стандартом шифрования во многих сферах — от банковских систем до защищённых коммуникационных каналов.
В данной статье мы рассмотрим подробную реализацию алгоритма AES на языке Python. Мы разберём основные этапы, такие как работа с блоками, ключевыми операциями алгоритма и организацию процесса шифрования и расшифровки. Кроме того, будет представлен пример готового к использованию кода с комментариями, что позволит не только понять логику работы AES, но и использовать данный код в своих проектах.
История и основные концепции AES
AES был утверждён Национальным институтом стандартов и технологий США (NIST) в 2001 году в качестве замены устаревшего DES. Алгоритм основан на шифре Rijndael, который был разработан бельгийскими криптографами Винсентом Рейменом и Джоаном Дайменом. Основным преимуществом AES является его высокая эффективность и безопасность.
AES — симметричный блочный шифр, работающий с блоками длиной 128 бит и ключами длиной 128, 192 или 256 бит. В основе алгоритма лежит множество преобразований над матрицами байтов, включающих замену байтов (SubBytes), циклический сдвиг строк (ShiftRows), смешение столбцов (MixColumns) и добавление ключевого раунда (AddRoundKey).
Основные параметры AES
| Параметр | Возможные значения | Описание | 
|---|---|---|
| Размер блока | 128 бит (16 байт) | Фиксирован в стандарте AES | 
| Длина ключа | 128, 192, 256 бит | Определяет уровень безопасности | 
| Количество раундов | 10 (для 128-бит), 12 (для 192-бит), 14 (для 256-бит) | Число итераций преобразований | 
Структура алгоритма AES
Основные операции AES организованы блоками в несколько раундов. Каждый раунд состоит из определенного набора преобразований, позволяющих обеспечить требуемую диффузию и устойчивость шифра. Рассмотрим подробнее этапы шифрования.
Алгоритм начинается с функции расширения ключа, которая генерирует набор раундовых ключей из исходного ключа. Затем исходный блок данных подвергается начальному преобразованию AddRoundKey. После этого следуют N-1 раундов, каждый из которых включает последовательное применение функций SubBytes, ShiftRows, MixColumns и AddRoundKey. В заключительном раунде операция MixColumns пропускается.
Основные стадия шифрования
- Key Expansion (Расширение ключа): Производит генерацию набора ключей для каждого раунда из исходного ключа.
 - AddRoundKey: XOR текущего состояния с раундовым ключом.
 - SubBytes: Замена каждого байта блока с использованием матрицы замены S-box.
 - ShiftRows: Циклический сдвиг строк матрицы состояния.
 - MixColumns: Линейное преобразование столбцов с целью диффузии.
 
Подготовка к реализации на Python
Прежде чем приступить к собственно коду, важно понять, как в Python лучше всего организовать представление блоков данных и выполнить необходимые математические операции. В основе лежит работа с байтовыми массивами и матрицами 4×4 (так называемое состояние).
Для удобства реализации используем стандартный тип bytearray для хранения блоков данных. Кроме того, потребуется постоянно работать с операцией XOR и выполнять замену байтов по таблице S-box. В Python можно реализовать эти механизмы с помощью списков и словарей.
Формат хранения данных и ключа
- Блок данных — массив из 16 байт (
bytearray), организованный как матрица 4×4 байтов. - Ключ — массив байт, длина которого может быть 16, 24 или 32 байта.
 - Результаты промежуточных операций — аналогичные структуры, для которых удобно реализовать функции преобразования.
 
Реализация основных компонентов AES на Python
Далее мы рассмотрим ключевые части программы — таблицу S-box, функции расширения ключа, а также все операции раундов. Код будет тщательно прокомментирован для понимания каждого шага.
Таблица подстановки S-box
S-box — это неизменяемая таблица замены байтов, обеспечивающая нелинейность шифра. Она реализована в виде списка из 256 элементов. Ниже представлен упрощённый пример заполнения (для полной реализации необходимо использовать полный массив из стандарта AES).
s_box = [
    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
    0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
    # ... всего 256 значений ...
]
Расширение ключа (Key Expansion)
Расширение ключа принимает исходный ключ и создает список раундовых ключей, используя функции RotWord, SubWord и константы Rcon. Ниже показан пример одной из реализаций функции расширения ключа.
def key_expansion(key):
    # Количество 32-битных слов ключа
    Nk = len(key) // 4
    Nr = Nk + 6
    Nb = 4
    w = [0] * (Nb * (Nr + 1))  # массив для слов ключей
    for i in range(Nk):
        w[i] = (key[4*i] << 24) | (key[4*i+1] << 16) | (key[4*i+2] << 8) | key[4*i+3]
    for i in range(Nk, Nb * (Nr + 1)):
        temp = w[i - 1]
        if i % Nk == 0:
            temp = sub_word(rot_word(temp)) ^ rcon[i // Nk]
        elif Nk > 6 and i % Nk == 4:
            temp = sub_word(temp)
        w[i] = w[i - Nk] ^ temp
    return w
Данные функции rot_word, sub_word и константа rcon также должны быть реализованы.
Функции преобразования в раундах
- SubBytes: заменяет каждый байт состояния согласно S-box.
 - ShiftRows: циклически сдвигает 2-ю, 3-ю и 4-ю строки в матрице состояния.
 - MixColumns: умножает каждый столбец на фиксированную матрицу в поле GF(2^8).
 - AddRoundKey: xor состояние с ключом раунда.
 
Пример функции SubBytes
def sub_bytes(state):
    for i in range(4):
        for j in range(4):
            state[i][j] = s_box[state[i][j]]
    return state
Пример функции ShiftRows
def shift_rows(state):
    state[1] = state[1][1:] + state[1][:1]
    state[2] = state[2][2:] + state[2][:2]
    state[3] = state[3][3:] + state[3][:3]
    return state
Пример функции MixColumns
def mix_columns(state):
    for i in range(4):
        a = state[0][i]
        b = state[1][i]
        c = state[2][i]
        d = state[3][i]
        state[0][i] = mul_by_02(a) ^ mul_by_03(b) ^ c ^ d
        state[1][i] = a ^ mul_by_02(b) ^ mul_by_03(c) ^ d
        state[2][i] = a ^ b ^ mul_by_02(c) ^ mul_by_03(d)
        state[3][i] = mul_by_03(a) ^ b ^ c ^ mul_by_02(d)
    return state
Функции mul_by_02 и mul_by_03 реализуют умножение в поле GF(2^8), которое требует отдельной реализации.
Полный пример шифрования одного блока
Ниже приведён схематичный пример полной функции шифрования одного 16-байтового блока данных с использованием ключа длиной 16 байт (AES-128).
def aes_encrypt_block(input_bytes, key):
    assert len(input_bytes) == 16
    assert len(key) == 16
    state = [list(input_bytes[i:i+4]) for i in range(0, 16, 4)]
    round_keys = key_expansion(key)
    state = add_round_key(state, round_keys[0:4])
    Nr = 10
    for round in range(1, Nr):
        state = sub_bytes(state)
        state = shift_rows(state)
        state = mix_columns(state)
        state = add_round_key(state, round_keys[round*4:(round+1)*4])
    state = sub_bytes(state)
    state = shift_rows(state)
    state = add_round_key(state, round_keys[Nr*4:(Nr+1)*4])
    encrypted = bytearray(sum(state, []))
    return encrypted
Каждая из вспомогательных функций (add_round_key, sub_bytes, shift_rows, mix_columns, и key_expansion) должна быть реализована, как обсуждалось ранее.
Практические советы по использованию AES в Python
Хотя реализация AES вручную полезна с учебной точки зрения, для промышленных задач рекомендуется использовать специализированные библиотеки, такие как cryptography или PyCryptoDome. Они обеспечивают безопасность, оптимизацию и соответствие текущим стандартам.
Если же необходимо самостоятельно реализовать алгоритм, важно уделить внимание корректной обработке ключей, правильному добавлению паддинга к данным (например, PKCS#7) для обработки блоков разной длины, а также учитывать режимы работы (ECB, CBC, CTR и др.) для повышения безопасности.
Режимы работы AES
| Режим | Описание | Особенности безопасности | 
|---|---|---|
| ECB | Каждый блок шифруется независимо | Уязвим к шаблонам, не рекомендуется для чувствительных данных | 
| CBC | Использует вектор инициализации, цепочечное шифрование | Безопаснее ECB, но требует случайного IV | 
| CTR | Потоковый режим, обратимый счетчик | Обеспечивает параллельную обработку и хорошую производительность | 
Заключение
Алгоритм AES является одним из самых надёжных и широко используемых методов шифрования. Его реализация на языке Python помогает понять внутренние механизмы работы блочных шифров и принципы криптографической защиты данных. В статье были рассмотрены основные этапы алгоритма, включая преобразования в раундах и расширение ключа.
Подробная реализация, хоть и требует внимания к деталям, открывает возможности для учебных целей и создания собственных криптоинструментов. При этом, для критически важных систем стоит применять проверенные криптобиблиотеки, которые обеспечивают необходимый уровень безопасности и оптимизации.
Надеемся, что этот материал поможет вам разобраться в практике реализации AES и применении его в реальных программах на Python.