Цифровая подпись
Опубликовано: 28.08.2023
цифровая подпись
Одним из механизмоваутентификации, которые я описал ранее, являютсякоды аутентификации сообщений, сокращенно называемые MAC. Пришло время представить другой тип алгоритмов, позволяющих реализовать эту услугу. Это будут цифровые подписи, реализованные с помощью асимметричных алгоритмов (анг. асимметричных алгоритмов). В этих алгоритмах есть пара ключей. До сих пор мы имели дело только ссимметричными алгоритмами, в которых имелся только секретный ключ.
Рукописная и цифровая подпись
Что связывает и что отличает рукописную подпись от ее цифрового аналога? Оба должны быть приписаны одному человеку и не подделать. Подписавшаяся сторона не должна иметь возможность их дезавуировать. Их также должно быть легко создавать и легко проверять. Цифровая подпись не обязательно должна быть физически связана с документом (она может храниться в другом файле) и всегда распространяется на весь документ. Рукописные подписи обычно ставятся на последней странице документа и одинаковы для всех подписываемых нами документов. Значение цифровой подписи зависит от документа и всегда распространяется на его целостность.
Алгоритмы, разработанные для цифровой подписи, состоят из трех частей: операции генерации ключа, операции создания подписи и операции проверки подписи. Конечно, однажды сгенерированные ключи можно использовать для создания нескольких подписей. Терминыцифровая подписьиэлектронная подписьчасто используются как взаимозаменяемые. Электронная подпись – это любая форма подписи, хранящейся в электронном виде. В этом смысле скан рукописной подписи будет считаться электронной подписью. Цифровая подпись — это подпись, основанная на криптографических механизмах. Далее я сосредоточусь нацифровых подписях.
Частный и открытый ключ
Используя асимметричные алгоритмы, пользователь после генерации ключей становится владельцем пары ключей. Один из них предназначен для выполнения операции подписи. Только владелец пары ключей должен иметь возможность генерировать подпись, поэтому этот ключ должен храниться в секрете, поэтому он называется закрытым ключом (закрытый ключ). Второй ключ используется в операции проверки подписи. Любой желающий может это сделать. Ключ для этой цели распространяется в виде открытого текста и называетсяоткрытым ключом). Невозможно отличить закрытый ключ от открытого ключа, даже если они связаны математическими отношениями. Если быть точнее: данная операция теоретически возможна, но из-за своей вычислительной сложности практически неосуществима при достаточно стойком ключе.
На рисунке ниже я представил типовую схему работы подписи. Подписывающая сторона вычисляет значение хеш-функции из документа и преобразует его с помощью закрытого ключа для получения значения подписи $$s$$. Верификатор самостоятельно вычисляет значение хеш-функции из представленного документа, а затем преобразует подпись с помощью открытого ключа, восстанавливая хэш документа, вычисленный подписавшим. Если вычисленные значения хэш-функции равны, подпись соответствует полученному документу и операция проверки завершается успешно. В противном случае документ или подпись были изменены и результат проверки отрицательный.
Здесь необходимо объяснить, почему подпись ставится не на документе, а на его сокращении. Это сделано из соображений безопасности и вытекает из принципов работы асимметричных алгоритмов. Использование хэш-функции предотвращает атаку, которая позволяет генерировать подписи для других документов на основе уже имеющихся документов с их подписями лица, не являющегося владельцем закрытого ключа. Чтобы точно понять, почему возможна такая атака, необходимо глубоко изучить асимметричные алгоритмы.
Алгоритм RSA
Закрытый ключ в алгоритме RSA (аббревиатура происходит от имен создателей:Ривест,Шамир,Адлеман[( 14501)]) — это пара чисел $$(d, n)$$, пара открытых ключей $$(e, n)$$. Число $$n$$ называетсямодулеми создается путем вычисления произведения двух больших случайных простых чисел $$p$$ и $$q$$, найденных при генерации ключа ($$ n = p * q$$). Закрытый ключ связан с числами $$p$$ и $$q$$, поэтому их необходимо хранить в секрете. Их произведение является компонентом открытого ключа, но в настоящее время мы не знаем эффективных алгоритмов факторизации произведений больших простых чисел. Сила алгоритма RSA основана на этой проблеме. Злоумышленник не может факторизовать модуль и определить значение $$d$$.
$$M$$ подписывается путем вычисления $$S = M^e mod n$$, обратная операция — $$M = S^d mod n$$. Обратите внимание, что это математические формулы, поэтому $$M$$ — число. Кроме того, для правильной работы операций $$M$$ должно быть меньше $$n$$. Это одна из причин, по которой вам необходимо использовать хэш-функцию для подписанных документов. Если бы мы подписывали весь документ, его следовало бы разделить на части, например $$(M_1, M_2, M_3)$$ таким образом, чтобы каждая из них соответствовала заданному условие $$M$$ меньше $$n$$. Для данного примера подпись также будет состоять из трех компонентов $$(S_1, S_2, S_3)$$. Исходя из этого, человек, не являющийся владельцем закрытого ключа, легко может обозначить подпись для документа $$(M_3, M_2, M_1)$$. Это будет $$(S_3, S_2, S_1)$$. Использование хэш-функции предотвратит такую атаку.
Следующая программа, реализованная на Java, на первом этапе работы генерирует пару ключей RSA длиной 2048 бит. На следующем этапе для примера сообщения вычисляется значение цифровой подписи с использованием хеш-функции SHA-256 (отмечено в SHA256сRSA). В этой операции участвует закрытый ключ. Затем эта подпись проверяется. На этом этапе используется только открытый ключ.
1 Импортировать Джава. безопасность. Ключевая пара ; 2 Импортировать Джава. безопасность. Генератор пары ключей ; 3 Импортировать Джава. безопасность. SecureRandom ; 4 Импортировать Джава. безопасность. подпись ; 5 6 общественный сорт RSATest { 7 общественный статический пустота основной ( Нить [ ] аргументы ) бросает исключение { 8 байт [ ] сообщение "=" "abcdefghijklmnoprstuwxyz1234567890!". getBytes ( ) ; 9 10 // генерируем ключи 11 Генератор пары ключей генератор ключей "=" Генератор пары ключей. получить экземпляр ( "РСА" ) ; 12 генератор ключей. инициализировать ( 2048, новый SecureRandom ( ) ) ; 13 Ключевая пара пара ключей "=" генератор ключей. генерировать ключевую пару ( ) ; 14 15 // объект для работы ЭЦП 16 подпись подписавший "=" подпись. получить экземпляр ( «SHA256сRSA» ) ; 17 18 // подписание 19 подписавший. initSign ( пара ключей. getPrivate ( ), новый SecureRandom ( ) ) ; 20 подписавший. обновлять ( сообщение ) ; 21 22 байт [ ] подписьзначение "=" подписавший. знак ( ) ; 23 24 // проверка подписи 25 подписавший. initVerify ( пара ключей. getPublic ( ) ) ; 26 подписавший. обновлять ( сообщение ) ; 27 28 Система. вне. println ( подписавший. проверять ( подписьзначение ) ) ; 29 } тридцать }Практически работу цифровой подписи RSA можно опробовать на себе. эта страница. Для самостоятельного эксперимента предлагаю нарушить значение подписи или попробовать проверить подпись под измененным сообщением. Также стоит наблюдать за зависимостью длины ключа от времени его генерации. Подробности о работе и реализации алгоритма RSA представлены в RFC 3447.
Эллиптические кривые
Проблема факторизации — не единственная вычислительно сложная проблема, используемая в криптографии с открытым ключом. В 1985 году Нил Коблиц и Виктор С. Миллер предложили использовать эллиптические кривые ((14500)]эллиптические кривые, сокращенно EC, в криптографии). Чтобы использовать алгоритмы на основе эллиптических кривых, необходимо выбрать конкретную кривую, которая определяется математической формулой. Такой параметр называется параметром домена (параметр домена). Открытым ключом на конкретной эллиптической кривой является одна из выбранных на ней точек.
В приведенной ниже программе показано, как работает ECDSA (Алгоритм цифровой подписи на основе эллиптических кривых). На первом этапе генерируется пара ключей с использованием эллиптической кривой, отмеченной именем секп256р1. Далее выполните операции подачи и проверки подписи. Формулу используемой кривой можно найти в документе Рекомендуемые параметры домена эллиптической кривой который содержит предложения по эллиптическим кривым для использования в криптографии.
1 Импортировать Джава. безопасность. Ключевая пара ; 2 Импортировать Джава. безопасность. Генератор пары ключей ; 3 Импортировать Джава. безопасность. SecureRandom ; 4 Импортировать Джава. безопасность. подпись ; 5 Импортировать Джава. безопасность. спецификация. ECGenParameterSpec ; 6 7 общественный сорт ECDSATest { 8 общественный статический пустота основной ( Нить [ ] аргументы ) бросает исключение { 9 байт [ ] сообщение "=" "abcdefghijklmnoprstuwxyz1234567890!". getBytes ( ) ; 10 11 Генератор пары ключей генератор ключей "=" Генератор пары ключей. получить экземпляр ( "ЭК" ) ; 12 генератор ключей. инициализировать ( новый ECGenParameterSpec ( "secp256r1" ), новый SecureRandom ( ) ) ; 13 Ключевая пара пара ключей "=" генератор ключей. генерировать ключевую пару ( ) ; 14 15 подпись подписавший "=" подпись. получить экземпляр ( «SHA256сECDSA» ) ; 16 17 подписавший. initSign ( пара ключей. getPrivate ( ), новый SecureRandom ( ) ) ; 18 подписавший. обновлять ( сообщение ) ; 19 20 байт [ ] подписьзначение "=" подписавший. знак ( ) ; 21 22 подписавший. initVerify ( пара ключей. getPublic ( ) ) ; 23 подписавший. обновлять ( сообщение ) ; 24 25 Система. вне. println ( подписавший. проверять ( подписьзначение ) ) ; 26 } 27 }Длина ключа, указанная на эллиптической кривой, определяется выбранной кривой. Тот, который используется в примере программы, позволяет генерировать ключи длиной 256 бит. С точки зрения безопасности это соответствует длине ключа алгоритма RSA в 3072 бита. Поскольку значительно более короткие ключи обеспечивают тот же уровень безопасности, алгоритмы эллиптических кривых становятся все более популярными.
Вы также можете поэкспериментировать с генерацией ключей и работой алгоритма подписи ECDSA. эта страница. Криптографические алгоритмы на основе элпитических кривых описаны в RFC 6090.
Краткое содержание
Асимметричные алгоритмы упрощают процесс обмена ключами между сторонами, поскольку открытый ключ является общедоступным, а закрытый ключ не является общим и нет необходимости создавать безопасный канал для его передачи. Это большое преимущество такого типа механизмов. Однако следует помнить, что открытые ключи, как и любые другие данные, также должны подвергаться процессу аутентификации. Как мы можем быть уверены, что открытый ключ принадлежит тому, кто его нам дал? Как мы узнаем, что этот человек также владеет закрытым ключом от предоставленного нам открытого ключа? Решением этой проблемы будет именно тот же механизм, который я описал выше. Открытые ключи также могут быть подписаны цифровой подписью. Такой документ, дополненный данными, идентифицирующими владельца данного открытого ключа, называется сертификатом открытого ключа). Подробнее я представлю их в одной из следующих записей.