Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

МСЗИ_23_ИСТ_1_1_Какушкина_Ольга_Витальевна_ЛР_5

.docx
Скачиваний:
0
Добавлен:
23.06.2025
Размер:
125.92 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Ф едеральное государственное бюджетное образовательное учреждение высшего образования

НИЖЕГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ

УНИВЕРСИТЕТ им. Р.Е.АЛЕКСЕЕВА

Институт радиоэлектроники и информационных технологий

Кафедра информатики и систем управления

ОТЧЕТ по лабораторной работе №5

АЛГОРИТМЫ ЭЛЕКТРОННОЙ ЦИФРОВОЙ ПОДПИСИ (ГОСТ Р 34.10-2018)

по дисциплине

Методы и средства защиты информации

(наименование дисциплины)

РУКОВОДИТЕЛЬ:

________________ Жуков М. С.

(подпись) (фамилия, и.,о.)

СТУДЕНТ:

________________ Какушкина О.В.

(подпись) (фамилия, и.,о.)

23-ИСТ-1-1

(шифр группы)

Работа защищена «___» ____________

С оценкой ________________________

Нижний Новгород 2025

Текст задания №5:

Реализовать процесс формирования и проверки электронной цифровой подписи по ГОСТ Р 34.10-2018.

1. ГОСТ Р 34.10-2018 - это российский стандарт электронной цифровой подписи, основанный на эллиптических кривых. Данный алгоритм является частью семейства криптографических стандартов ГОСТ и предназначен для обеспечения целостности и аутентичности цифровых данных.Описание алгоритма RSA с цифровой подписью

2. Основные понятия

  • Эллиптическая кривая: математический объект, заданный уравнением y² = x³ + ax + b над конечным полем

  • Базовые параметры: набор параметров (p, a, b, q, P), определяющих конкретную кривую

  • Закрытый ключ: случайное число d в диапазоне [1, q-1]

  • Открытый ключ: точка Q на кривой, вычисляемая как Q = d*P

  • Хеш-функция: используется Streebog (ГОСТ Р 34.11-2012) длиной 256 или 512 бит

3. Описание алгоритма

3.1. Генерация ключей

  1. Выбирается случайное число d в диапазоне от 1 до q-1 (порядок базовой точки)

  2. Вычисляется точка Q = d*P (умножение точки на скаляр)

  3. Пара (d, Q) становится парой закрытый/открытый ключ

3.2. Формирование подписи

  1. Вычисляется хеш сообщения h = Hash(M)

  2. Преобразуется хеш в число e = h mod q (если e = 0, устанавливается e = 1)

  3. Генерируется случайное число k в диапазоне от 1 до q-1

  4. Вычисляется точка C = k*P

  5. Вычисляется r = x_C mod q (x-координата точки C)

  6. Если r = 0, процесс повторяется с новым k

  7. Вычисляется s = (rd + ke) mod q

  8. Если s = 0, процесс повторяется с новым k

  9. Подпись - пара (r, s)

3.3. Проверка подписи

  1. Проверяется, что 0 < r < q и 0 < s < q

  2. Вычисляется хеш сообщения h = Hash(M)

  3. Преобразуется хеш в число e = h mod q (если e = 0, устанавливается e = 1)

  4. Вычисляется v = e⁻¹ mod q (обратный элемент)

  5. Вычисляются z₁ = (sv) mod q и z₂ = (-rv) mod q

  6. Вычисляется точка C = z₁P + z₂Q

  7. Вычисляется R = x_C mod q (x-координата точки C)

  8. Подпись верна, если R = r

Реализация алгоритма

import hashlib import random from typing import Tuple class Streebog: """Класс-заглушка для хеш-функции ПО ГОСТ""" @staticmethod def hash256(message: bytes) -> bytes: return hashlib.sha256(message).digest() @staticmethod def hash512(message: bytes) -> bytes: """Временная замена Streebog-512 на SHA-512 (для тестирования)""" return hashlib.sha512(message).digest() class GOST34102018: def __init__(self, p: int, a: int, b: int, q: int, P: Tuple[int, int]): """ Инициализация параметров эллиптической кривой :param p: модуль поля :param a: коэффициент a уравнения кривой :param b: коэффициент b уравнения кривой :param q: порядок подгруппы :param P: базовая точка подгруппы """ self.p = p self.a = a self.b = b self.q = q self.P = P # Определяем длину подписи в битах (256 или 512) self.l = 256 if q.bit_length() <= 256 else 512 def _hash(self, message: bytes) -> int: """Реализация хеширования """ if self.l == 256: hash_bytes = Streebog.hash256(message) else: hash_bytes = Streebog.hash512(message) return int.from_bytes(hash_bytes, 'little') def _inverse(self, a: int, n: int) -> int: """Нахождение обратного элемента по модулю (расширенный алгоритм Евклида)""" t, newt = 0, 1 r, newr = n, a while newr != 0: quotient = r // newr t, newt = newt, t - quotient * newt r, newr = newr, r - quotient * newr if r > 1: raise ValueError("Обратного элемента не существует") if t < 0: t += n return t def _add_points(self, P: Tuple[int, int], Q: Tuple[int, int]) -> Tuple[int, int]: """Сложение точек на эллиптической кривой""" if P == (0, 0): return Q if Q == (0, 0): return P if P[0] == Q[0] and (P[1] + Q[1]) % self.p == 0: return (0, 0) if P != Q: # Лямбда для сложения разных точек numerator = (Q[1] - P[1]) % self.p denominator = (Q[0] - P[0]) % self.p lambd = (numerator * self._inverse(denominator, self.p)) % self.p else: # Лямбда для удвоения точки numerator = (3 * P[0] ** 2 + self.a) % self.p denominator = (2 * P[1]) % self.p lambd = (numerator * self._inverse(denominator, self.p)) % self.p x3 = (lambd ** 2 - P[0] - Q[0]) % self.p y3 = (lambd * (P[0] - x3) - P[1]) % self.p return (x3, y3) def _multiply_point(self, k: int, point: Tuple[int, int]) -> Tuple[int, int]: """Умножение точки на скаляр """ result = (0, 0) # Нейтральный элемент addend = point while k > 0: if k & 1: result = self._add_points(result, addend) addend = self._add_points(addend, addend) k >>= 1 return result def generate_keys(self) -> Tuple[int, Tuple[int, int]]: """Генерация пары ключей (закрытый и открытый)""" d = random.randint(1, self.q - 1) # Закрытый ключ Q = self._multiply_point(d, self.P) # Открытый ключ return d, Q def sign(self, message: bytes, d: int) -> Tuple[int, int]: """Формирование подписи для сообщения""" # Шаг 1: Вычисление хеша сообщения h = self._hash(message) # Шаг 2: Преобразование хеша в число e e = h % self.q if e == 0: e = 1 while True: # Шаг 3: Генерация случайного числа k k = random.randint(1, self.q - 1) # Шаг 4: Вычисление точки C = k*P и параметра r C = self._multiply_point(k, self.P) r = C[0] % self.q if r == 0: continue # Шаг 5: Вычисление параметра s s = (r * d + k * e) % self.q if s == 0: continue # Шаг 6: Возврат подписи (r, s) return r, s def verify(self, message: bytes, signature: Tuple[int, int], Q: Tuple[int, int]) -> bool: """Проверка подписи для сообщения""" r, s = signature # Шаг 1: Проверка диапазонов r и s if not (0 < r < self.q and 0 < s < self.q): return False # Шаг 2: Вычисление хеша сообщения h = self._hash(message) # Шаг 3: Преобразование хеша в число e e = h % self.q if e == 0: e = 1 # Шаг 4: Вычисление v = e^-1 mod q v = self._inverse(e, self.q) # Шаг 5: Вычисление z1 и z2 z1 = (s * v) % self.q z2 = (-r * v) % self.q # Шаг 6: Вычисление точки C = z1*P + z2*Q z1P = self._multiply_point(z1, self.P) z2Q = self._multiply_point(z2, Q) C = self._add_points(z1P, z2Q) # Шаг 7: Проверка условия R == r mod q R = C[0] % self.q return R == r # Пример параметров для 256-битной подписи p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97 a = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94 b = 0x00000000000000000000000000000000000000000000000000000000000000A6 q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893 P = (0x0000000000000000000000000000000000000000000000000000000000000001, 0x8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14) # Создание экземпляра класса с параметрами gost = GOST34102018(p, a, b, q, P) # Генерация ключей d, Q = gost.generate_keys() print(f"Закрытый ключ: {d}") print(f"Открытый ключ: ({Q[0]}, {Q[1]})") # Сообщение для подписи - "Кушина Ольга" (в кодировке UTF-8) message = "Какушина Ольга".encode('utf-8') # Формирование подписи signature = gost.sign(message, d) print(f"Подпись: (r={signature[0]}, s={signature[1]})") # Проверка подписи is_valid = gost.verify(message, signature, Q) print(f"Подпись верна: {is_valid}") # Проверка с измененным сообщением (должно вернуть False) fake_message = "Какушкина Ольга".encode('utf-8') is_valid_fake = gost.verify(fake_message, signature, Q) print(f"Проверка с другим сообщением: {is_valid_fake}")

Вывод программы

Вывод:

В ходе лабораторной работы я написала алгоритм ГОСТ Р 34.10-2018. Он предоставляет надежный механизм создания и проверки электронных цифровых подписей, соответствующий российским криптографическим стандартам. Использование эллиптических кривых обеспечивает высокий уровень безопасности при относительно небольших размерах ключей.