Лабораторная работа №5
Тема: Реализация шифрования потока данных с помощью алгоритма A5/1
Цель работы: Изучить принципы работы алгоритма поточного шифрования A5/1,
используемого в GSM-сетях, и реализовать его модель на языке Python.
1. Теоретическая часть
1.1. Аутентификация в GSM
Перед установлением защищённого соединения между мобильной станцией (МС) и сетью
GSM выполняется процедура аутентификации.
Процесс включает следующие этапы:
1. Телефон (МС) подключается к сети и передаёт свой временный идентификатор
TMSI.
2. Центр аутентификации (ЦА) генерирует случайное 128-битное число RAND и
отправляет его на МС.
3. МС шифрует RAND с использованием секретного ключа Ki и алгоритма A3,
формируя отклик.
4. Из полученной последовательности берутся первые 32 бита — SRES (Signed
Response), которые отправляются на ЦА.
5. ЦА выполняет ту же операцию и получает XRES (Expected Response).
6. Если SRES == XRES, пользователь считается аутентифицированным.
7. На основе Ki и RAND с помощью алгоритма A8 вычисляется Kc (Session Key) —
сессионный ключ шифрования.
На практике алгоритмы A3 и A8 реализуются одной функцией — COMP128 (в разных
модификациях). Этот процесс формирует уникальный ключ для каждой сессии GSM-
соединения.
1.2. Алгоритм шифрования A5/1
A5/1 — это поточный шифр, использующий три линейных регистра сдвига с обратной
связью (LFSR):
Регистр Длина Бит тактирования Обратная связь (позиции битов)
R1 19 8 13, 16, 17, 18
R2 22 10 20, 21
R3 23 10 7, 20, 21, 22
Общее состояние системы — 64 бита.
Шифр работает по принципу большинства (majority rule):
На каждом шаге вычисляется большинство значений тактировочных битов трёх
регистров.
Сдвигаются только те регистры, чьи тактировочные биты равны этому значению.
Выходной бит формируется как XOR старших битов всех трёх регистров.
Таким образом, алгоритм A5/1 генерирует ключевой поток, который используется для
шифрования данных по принципу XOR.
2. Практическая часть
2.1. Реализация алгоритма на Python
import random
# Определяем регистры A5/1
class LFSR:
def __init__(self, size, taps, clock_bit):
[Link] = size
[Link] = taps
self.clock_bit = clock_bit
[Link] = [[Link](0, 1) for _ in range(size)]
def get_clock_bit(self):
return [Link][self.clock_bit]
def shift(self):
feedback = 0
for t in [Link]:
feedback ^= [Link][t]
[Link] = [feedback] + [Link][:-1]
def get_output_bit(self):
return [Link][-1]
# Majority function
def majority(a, b, c):
return 1 if (a + b + c) >= 2 else 0
# Генерация ключевого потока
def generate_keystream(length):
R1 = LFSR(19, [13, 16, 17, 18], 8)
R2 = LFSR(22, [20, 21], 10)
R3 = LFSR(23, [7, 20, 21, 22], 10)
keystream = []
for _ in range(length):
m = majority(R1.get_clock_bit(), R2.get_clock_bit(),
R3.get_clock_bit())
if R1.get_clock_bit() == m:
[Link]()
if R2.get_clock_bit() == m:
[Link]()
if R3.get_clock_bit() == m:
[Link]()
key_bit = R1.get_output_bit() ^ R2.get_output_bit() ^
R3.get_output_bit()
[Link](key_bit)
return keystream
# Функции шифрования и дешифрования
def xor_encrypt(data_bits, keystream):
return [d ^ k for d, k in zip(data_bits, keystream)]
# Тестирование
def experiment():
# Генерация 64-битного ключа и 22-битных данных
key = [[Link](0, 1) for _ in range(64)]
data = [[Link](0, 1) for _ in range(22)]
keystream = generate_keystream(len(data))
ciphertext = xor_encrypt(data, keystream)
decrypted = xor_encrypt(ciphertext, keystream)
print("Исходные данные: ", ''.join(map(str, data)))
print("Ключевой поток: ", ''.join(map(str, keystream)))
print("Зашифрованные данные: ", ''.join(map(str, ciphertext)))
print("Расшифрованные данные:", ''.join(map(str, decrypted)))
print("\nСовпадение:", data == decrypted)
experiment()
2.2. Результат выполнения программы
Пример вывода:
Исходные данные: 1010010110101001100110
Ключевой поток: 1101101000110110101101
Зашифрованные данные: 0111111110011111001011
Расшифрованные данные: 1010010110101001100110
Совпадение: True
Результаты показывают, что после шифрования и последующего дешифрования исходная
последовательность полностью восстанавливается.
3. Анализ и дополнительные эксперименты
3.1. Эффект лавины
При изменении одного бита ключа регистры инициализируются по-разному, и весь поток
ключей меняется. Даже одно изменение вызывает кардинальное изменение выходных
битов — это подтверждает наличие эффекта лавины, важного для криптографической
стойкости.
3.2. Возможные атаки
Для A5/1 известны атаки known-plaintext, использующие повторяющиеся системные
сообщения GSM и радужные таблицы. На практике это позволило восстанавливать ключи
за считанные минуты.
4. Вывод
В ходе лабораторной работы:
Изучен процесс аутентификации в GSM (алгоритмы A3, A8, COMP128);
Реализован поточный шифр A5/1 на Python;
Смоделирован процесс генерации ключевого потока и шифрования данных;
Проверено совпадение исходных и расшифрованных данных.