ИНФОРМАЦИЯ

Прозрачное шифрование трафика канального уровня

Данная статья рассматривает теоретические аспекты шифрования. Пример практической реализации описан в статье Шифрование Ethernet на скорости 1Gbps.

Введение

С ростом современных организаций возрастают и её информационные потребности в вычислительных ресурсах по обработке данных. Это
подразумевает растущее количество оборудования соединённого сетью. Организация может иметь географически разнесённые офисы, подразделения,
которые необходимо объединять в общую корпоративную сеть.

Связь между офисами на канальном уровне

Нередко провайдеры телекоммуникационных услуг предоставляют возможность соединения офисов выделенными линиями связи. Как правило, это
проброшенные Ethernet каналы между подразделениями компании и провайдером. Так как пакеты сетевого трафика между подразделениями идут
напрямую между офисами минуя Интернет — это обеспечивает высокую производительность, меньшие задержки и низкую себестоимости связи.
Хотя целесообразность прямого канала связи между подразделениями имеется лишь при ощутимых объёмах циркулирующей корпоративной информации.

Сложность технической инфраструктуры организации может быть высока, и обеспечение конфиденциальности передаваемых данных между офисами
трудоёмче. Присутствующее третье лицо (провайдер) легко произведёт атаки вида человек-посередине.

Проблема шифрования на сетевом уровне

Преобладающая часть программно-аппаратных средств по шифрованию трафика работает на третьем и более высоких сетевых уровнях. Логические
структуры и организация сетей третьего уровня, зачастую, отдалённо коррелирует со структурой низлежащей сети второго. Из-за этого,
создание виртуальных частных криптографически защищённых сетей является не тривиальной задачей, затрагивающей всю систему маршрутизации.

Прозрачное шифрование трафика именно на втором уровне избавит от изменений в маршрутизации, уменьшит накладные расходы от туннелирования
сетевых пакетов. Проще организовать обмен криптографическими ключами между подразделениями одной организации и сократить сложные протоколы и процедуры установления общего ключа. Задержки связи из-за использования симметричной криптографии со статическими ключами отсутствуют. Кроме того, объёмы трафика останутся неизменны.

В данной статье будет рассмотрена собственная простая реализация подобного шифрования. Предполагается что на каждом конце двухточечного
канала связи имеется компьютер с двумя Ethernet-портами: один из которых подключён к зашифрованному каналу связи, а другой к сети подразделения организации. На данном компьютере и установлено рассматриваемое здесь программное обеспечение.

В приведённой программе шифруется только полезная нагрузка Ethernet-фреймов, но не их заголовки (например содержащие адреса
отправителя и получателя — деанонимизирующая участников сети).

Приведённая программа носит исключительно “академический” характер. Для промышленного использования могут понадобится доработки по
оптимизации производительности.

Детальное рассмотрение прозрачного шифратора

Рассмотрим программу транзитного прозрачного шифрования трафика. Данная программа “собирает” все приходящие на сетевой интерфейс IFACE_IN пакеты, шифрует их и отправляет по интерфейсу IFACE_OUT. Для простоты все пакеты друг от друга независимы — каждый пакет обрабатывается независимо от других.

Схема шифрования на канальном уровне
Рис. 1. Схема шифрования на канальном уровне

Аналогии с режимами шифрования блочных шифров

Наилучшим решением было бы консолидирование всего трафика и отправка в виде сплошного последовательного потока исходящих
Ethernet-фреймов. Зашифрованные по отдельности фреймы представляют из себя подобие ECB (Electronic Codebook (режим электронной кодовой книги)) режима шифрования симметричных блочных шифров. Это простейший режим и самый уязвимый. Один и тот же набор входных данных всегда имеет одно и то же зашифрованное представление. Путём несложного анализа трафика можно легко сопоставить входные и выходные пакеты. Это даёт возможность “атаковать” шифр с известным открытым текстом (plaintext-known attack). Более того, зашифрованные пакеты можно
посылать третьей стороной заново, что приведёт к атаке повторного воспроизведения (replay attack), или же к возможности отказа от
обслуживания (Denial-of-Service attack).

Режим сцепления блоков шифротекста (Cipher Block Chaining (CBC)) был бы панацеей, однако в среде Ethernet, где возможны потери пакетов,
необходимы правила восстановления криптографической синхронизации отправителя и получателя. Вариантом решения может быть режим обратной
связи по шифротексту (Cipher Feedback (CFB)).

Противостояние атакам

Как было сказано, в данной статье используется изолированное рассмотрение каждого Ethernet-фрейма, но с динамически меняющимся во
времени вектором инициализации (Initialization Vector (IV)) CBC-режима. Отправитель и получатель обязаны точно синхронизировать часы — для этого потребуется или третий сервер или ещё одно стороннее подключение между сторонами. Это не исключит возможности атаки на шифр с известным открытым текстом, но зато сократит время возможного проведения атаки повторного воспроизведения всего-лишь на дельту используемых сторонами часов. Чем выше точность синхронизации часов, тем меньшую дельту времени можно использовать и сузить временное окно проведения атаки.

Вектор инициализации также зависит от источника и получателя Ethernet-фрейма. Что также сужает круг доступных для атаки целей.

Генерирование вектора инициализации
Рис. 3. Генерирование вектора инициализации

Режим блочного шифрования и дополнение данных

В качестве основного инструментария примеров из статьи используется программа Scapy, написанная на языке программирования Python. Предоставляющая среду для высокоуровневого манипулирования пакетами второго и третьего сетевых уровней, их отправку и приём. Все приведённые примеры исполняются внутри данной среды. А также будет использована библиотека PyCrypto для всех криптографических функций (кроме источника псевдослучайных чисел).

Дополнение данных

Набор потоковых симметричных шифров библиотеки PyCrypto не велик — XOR, не являющийся шифрованием как таковым, и ARC4, являющийся слабым и абсолютно не пригодным для “промышленного” использования. Поэтому используются блочные шифры, что диктует требование кратности длины полезной нагрузки фреймов размеру блоку шифра. В противном случае, придётся делать процедуру дополнения данных (padding). Здесь будет
использована инвертированная схема ISO 10126 стандарта: дополнение данных случайными и указание их длины данных в конце сообщения. В
приведённой программе дополнение будут вставляться в начало полезной нагрузки, что устраняет возможность атаки шифра по известному открытому тексту.

Ethernet фрейм с padding-ом
Рис. 4. Ethernet фрейм с padding-ом

Побочным эффектом padding-а является увеличение длины полезной нагрузки Ethernet-пакета. Если её длина превзойдёт максимально допустимый размер фрейма (Maximum Transmission Unit (MTU)), то его не получится отправить. Решить данную проблему конкретно для Ethernet-среды можно либо дифференциацией значения MTU входного и выходного сетевых интерфейсов, либо использованием jumbo-фреймов.

Шифрование трафика

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

 1      from scapy.all import sniff, sendp
 2      from Crypto.Cipher import Blowfish
 3      from Crypto.Hash import SHA256
 4      import time
 5      import os

Подключение библиотеки Scapy с функциями “сбора” пакетов на сетевом интерфейсе (sniff) и отправки пакетов (sendp), алгоритма шифрования Blowfish (здесь он используется из-его патентной “чистоты”, производительности и простоты использования — смена на любой другой поддерживаемый алгоритм в данной библиотеке тривиальна), хэш-функции SHA256, а также библиотек доступа к системным часам и
ядерного (ядра операционной системы) источника псевдослучайных чисел.

 7      KEY = "995b1ea68ac289814cb8396d...aa92f73f17b2852c2dc990289e8e7"
 8      IFACE_IN = "eth0"
 9      IFACE_OUT = "eth1"

Используемый для шифрования/дешифрования ключ. Входной и выходной
сетевые интерфейсы.

11      BLOCKSIZE = 8
12
13      str_concat = lambda a: reduce( lambda s, c: s + c, a )
14
15      KEY_BINARY = str_concat([ chr( int( KEY[ i:i+2 ], 16 ) ) for i in
16                                range( 0, len( KEY ), 2 ) ])

Размер блока в используемом шифроалгоритме равен в большинстве случаев 64-м битам (8 байт). Объявление функции конкатенации массива строк (str_concat) — данная функция является исключительно вспомогательной для упрощения кода программы. Преобразование ключа, записанного в шестнадцатеричном формате в бинарный вид.

18      def iv( src, dst ):
19              h = SHA256.new()
20              h.update( src + dst + str( int( time.time() ) )[ :-1 ] )
21              ba = bytearray( h.digest() )
22              return str_concat([
23                      chr( ba[i] ^
24                           ba[i+BLOCKSIZE] ^
25                           ba[i+BLOCKSIZE*2] ^
26                           ba[i+BLOCKSIZE*3] ) for i in range(BLOCKSIZE)
27              ])

Функция вычисления вектора инициализации для CBC режима. Длина вектора инициализации должна совпадать с размером блока шифротекста (64 бита). В данной программе используется хэш-функция для создания динамически меняющейся по времени байтовой последовательности постоянной длины. На вход данной функции подаются:

  • адрес отправителя Ethernet-фрейма;
  • адрес получателя Ethernet-фрейма;
  • текущая временная дельта часов. В данной программе с помощью функции time() получается текущее значение времени с точностью до десяти секунд. Так как отправитель и получатель в ходе экспериментов не были синхронизированы с достаточной точностью.

Так как на выходе хэш-функция SHA256 имеет 256-битную последовательность, то необходимо сократить этот набор до требуемых нам
64-х бит. К сожалению, это значительно увеличивает возможность проведения атаки “дней рождения” (birthday attack), но, в то же время,
атакующему необходимо иметь и существующие требуемые адреса отправителя и получателя, что является трудоёмкой задачей. Для сокращения длины хэша мы просто произведём операцию логического исключающего ИЛИ между четырьмя равными частями хэша.

29      def pad( data ):
30              data_length = len( data ) + 1
31              if data_length >= BLOCKSIZE:
32                      size = data_length % BLOCKSIZE
33              else:
34                      size = data_length
35              size = BLOCKSIZE - size
36              return str( size ) + os.urandom(size) + data

Функция дополнения данных. В самое начало данных записывается (в ASCII кодировке) количество дополнительно добавленных данных (в данной
программе это может быть число от нуля до семи). Далее следует соответствующее количество псевдослучайных байтов и полезная нагрузка.
Псевдослучайные данные берутся из “быстрого” пула энтропии операционной системы (в большинстве операционных систем это устройство
/dev/urandom). Более криптографически надёжный источник, такой как /dev/random, не используется по причине эмпирической “медленности”, (без применения аппаратных генераторов).

38      def enc( pkt ):
39              crypt_obj = Blowfish.new(
40                      KEY_BINARY,
41                      Blowfish.MODE_CBC,
42                      iv( str( pkt.src ), str( pkt.dst ) )
43              )
44              pkt.payload = crypt_obj.encrypt( pad( str( pkt.payload ) ) )
45              sendp( pkt, iface = IFACE_OUT )

Функция обработки приходящих Ethernet-фреймов. В ней создаётся объект алгоритма шифрования с настройкой соответствующего ключа, CBC
режима шифрования и вектором инициализации. Затем, полезная нагрузка Ethernet-фрейма дополняется и шифруется. После этого, фрейм отправляется на выходной сетевой интерфейс.

47      sniff( iface = IFACE_IN, prn = enc )

Запуск процесса анализа всех приходящих Ethernet-пакетов по интерфейсу eth0. При этом указывается что каждый пакет необходимо “обработать” вышеуказанной функцией шифрования и отправки.

Дешифрование трафика

На противоположном конце от устройства шифрующего трафик должно быть дешифрующее. Программа для него полностью идентична рассмотренной в
предыдущей главе, за исключением её конечной части, имеющей функцию самой дешифрации и удаления дополненных данных (unpadding).

29      def unpad( data ):
30              return data[ int(data[0])+1: ]

Данная функция считывает первый байт данных, содержащий количество дополненных после него данных, и “отбрасывает” дополнение.

32      def dec( pkt ):
33              crypt_obj = Blowfish.new(
34                      KEY_BINARY,
35                      Blowfish.MODE_CBC,
36                      iv( str( pkt.src ), str( pkt.dst ) )
37              )
38              try: pkt.payload = unpad( crypt_obj.decrypt( str( pkt.payload ) ) )
39              except: pass
40              sendp( pkt, iface = IFACE_OUT )

Функция обработки приходящих Ethernet-фреймов. Аналогична функции enc(), за исключением того что сначала вызывается функция дешифрации, а затем удаления дополненных данных. При синхронизированных часах отправителя и получателя вычисляемые векторы инициализации совпадают и дешифрованные данные никак не искажаются. Если же синхронизация нарушена, или третья сторона пытается вставить собственные пакеты данных, то данные полностью искажаются в не интерпретируемый сетевыми устройствами шум.

42      sniff( iface = IFACE_IN, prn = dec )

Запуск процесса анализа и сбора приходящих Ethernet-пакетов.

Выводы

При шифровании трафика на втором уровне, вместо третьего, между соединёнными подразделениями одной организации:

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

Осуществить это легко: поставив на обоих концах канала связи по устройству с двумя сетевыми портами (один связан с противоположным
концом, а другой с сетью подразделения организации), со специализированным программным обеспечением (шифратором и дешифратором
проходящих Ethernet-фреймов).

Доработав приведённое в данной статье программное обеспечение до использования CFB режима шифрования, можно свести на нет всё ещё
возможные атаки (birthday replay, known-plaintext), убрать особенности связанные с дифференцированным MTU и наличие сервера времени.

НОВОСТИ

Последние новости