RSA в качестве алгоритма цифровой подписи



Алгоритм RSA можно использовать, как для обеспечения секретности, так и для формирования ЭЦП.

С точки зрения цифровой подписи нет необходимости в шифровании сообщения целиком. Вполне достаточно сгенерировать хеш исходного сообщения и зашифровать этот небольшой по размеру объект своим секретным ключом. Любой, располагающий соответствующим открытым ключом (то есть, кто угодно), сможет расшифровать хеш и верифициро­вать его. Если дешифрованный хеш совпадет с вновь вычисленным хе­шем, получатель может увериться в том, что сообщение отправлено именно владельцем соответствующего секретного ключа и с момента на­ложения подписи никем не изменено. Уверенность эта проистекает из того обстоятельства, что крайне трудно подобрать второе сообщение, ко­торое дало бы при вычислении точно такой же хеш.

Алгоритм цифровой подписи DSA

Алгоритм DSA является федеральным стандартом NIST, используемым совместно со стандартом SHA (Secure Hash Algorithm - хеширующий криптографический алгоритм). Институт NIST опубликовал первую вер­сию алгоритма DSA, как составную часть стандарта DSS (Digital Signatu­re Standard - Стандарт цифровой подписи, FIPS 186) в мае 1994 года. DSA основывается на задаче дискретных логарифмов.

Иерархия класса AsymmetricAlgorithm

Иерархия наследования класса асимметричного алгоритма, располагаю­щаяся в пространстве имен System.Security.Cryptography, приведена на рисунке 4.1 (см. Лабораторную работу № 4). На рисунке не показано, что AsymmetricAlgorithm произво­дится из класса Object. Класс AsymmetricAl­gorithm является абстрактным классом, и из него производятся классы DSA и RSA, которые также являются абстрактными. Из классов DSA и RSA затем производятся классы RSACryptoServiceProvider и DSACryptoServiceProvider, которые и обеспечивают реализацию алгоритмов RSA и DSA. Оба они используют поддержку CryptoAPI. Можно самостоя­тельно реализовать RSA или DSA или воспользоваться сторонней реали­зацией, но все же в большинстве случаев рекомендуется использовать реализацию .NET.

В данной лабораторной работе будут использоваться внешние методы и свойства класса DSACryptoServiceProvider. Как и вообще для любого симметричного или симметричного алгоритма, конструктор этого класса автоматически генерирует ключевую информацию в момент создания экземпляра.

 

Класс DSACryptoServiceProvider

Класс DSACryptoServiceProvider имеет следующие внешние (public) свойства класса:

· KeyExchangeAlgorithm    - получает имя алгоритма обмена ключами;

· KeySize                    - получает размер ключа в битах;

· LegalKeySizes           - получает разрешенные размеры ключей;

· PersistKeyInCsp       - определяет, должен ли ключ быть приоритетным в CSP;

· SignatureAlgorithm - получает имя алгоритма цифровой подписи.

Также класс DSACryptoServiceProvider обладает несколькими внешними методами. В функциях, обеспечивае­мых этими методами, наблюдается некоторая избыточность, а это означает, что одну и ту же задачу можно решить разными способами.

Наиболее важные из внешних методов класса  SACryptoServiceProvider:

· CreateSignature - создает подпись DSA для заданного сообщения;

· VerifySignature - верифицирует подпись DSA для заданного сооб­щения;

· SignData          - вычисляет хеш сообщения и подписывает результат;

· VerifyData       - верифицирует заданную подпись, сравнивая ее с под­писью, вычисленной для заданного сообщения;

· SignHash         - вычисляет подпись для заданного значения хеша;

· VerifyHash              - верифицирует заданную подпись, сравнивая ее с под­писью, вычисленной для заданного хеша;

· ToXmlString    - создает и возвращает XML-представление текущего
объекта DSA;

· FromXmlString - создает объект DSA из XML-данных;

· ExportParameters    - экспортирует параметры DSA в объект DSAParameters;

· ImportParameters    - импортирует параметры DSA из объекта DSAParameters.

Пример  приложения с использованием ЭЦП  RSA

Данный пример  показывает, как создать и верифици­ровать для сообщения ЭЦП RSA. На рисунке 3.4 изображено окно приложения, в котором генерируется и верифицируется цифровая подпись. Приложение работает следующим образом:

1. При нажатии на кнопку «Получить ЭЦП»  создается хеш исходного сообщения с помощью хеш-функции SHA-1 и ЭЦП RSA;

2. Затем, не меняя исходного сообщения, можно проверить подпись щелчком на кнопке «Проверка ЭЦП». При этом появится окно сообщения, удостоверяющее, что подпись подлинна (см. рисунок 3.5).

3. Если снова создать ЭЦП щелчком на кнопке «Получить ЭЦП», а затем изменить («подделать») сообщение в текстовом поле перед тем, как щелкнуть на кнопку «Проверка ЭЦП», то появится сообщение о недействительности подписи. Таким образом, программа обнаружит факт подделки сообщения.

Данный пример является искусственным, поскольку гене­рация подписи и ее проверка выполняются в пределах одного окна. Это сделано для удобства, чтобы продемонстрировать все аспекты работы с цифровой подписью в одном компактном приложении. В реальной жиз­ни применение цифровой подписи больше похоже на сценарий «кли­ент-сервер» или на распределенное приложение.

В таблице 3.1 приведено описание используемых в приложении элементов управления

 

Таблица  3.1 – Элементы управления

Элемент управления Класс Описание
1 2 3
groupBox1 GroupBox Панель группировки «Исходное сообщение»
groupBox2 GroupBox Панель группировки «Дайджест сообщения с использованием алгоритма SHA1»
groupBox3 GroupBox Панель группировки «ЭЦП RSA»
groupBox4 GroupBox Панель группировки «Параметры ЭЦП RSA»
label1 label Метка «Модуль»

Продолжение таблицы 3.1

1 2 3
label2 Label Метка «Экспонента»
textOriginalMessage TextBox Исходное сообщение
textMessageDigestSHA1 TextBox Дайджест исходного сообщения, полученный с помощью хеш-функции SHA-1
textSignature TextBox ЭЦП исходного сообщения, полученная с помощью алгоритма RSA
textBoxModulus TextBox Параметр «Модуль» ЭЦП RSA
textBoxExponent TextBox Параметр «Экспонента» ЭЦП RSA
buttonSign Button Командная кнопка «Получить ЭЦП»
buttonVerify Button Командная кнопка «Проверка ЭЦП»

 

 

 

 

 

 


Последовательность программирования приложения:

1. Определение глобальных переменных. В данном примере глобальные переменные связывают процесс формирования и верификации ЭЦП:

Для передачи информации между методами формирования и верификации ЭЦП в данном примере исполь­зуются два поля. Первое из них - объект RSAParameters. Этот объект инкапсулирует информацию открытого ключа. Второе поле - байтовый массив, содержащий цифровую подпись сообщения, сге­нерированную первым методом.

Хотя фактический текст сообщения тоже должен передаваться каким-то образом от подписывающего метода к методу, проверяющему подпись, в данном примере  нет отдельного поля для него. Вместо этого текст хранится и извлекается обоими методами прямо из тек­стового поля пользовательского интерфейса, благодаря чему пользователь может его изменять. Такая организация работы программы дает возмож­ность наглядно убедиться в последствиях любой подделки сообщения. В реальном сценарии текст должен передаваться, как дан­ные, между двумя приложениями.

//переменные для передачи информации между двумя //процедурами

   RSAParameters rsaparams;

   byte[] signaturebytes;

 

3. Событие Click кнопки buttonSign

Метод buttonSign_Click накладывает под­пись на сообщение. Код данной процедуры генерирует хеш, который затем подписывается вызовом метода SignHash объекта RSA. Метод ExportParameters используется для сохранения открытого ключа в объекте RSAParameters, что позволит использовать его для верификации. Для верификации необходим только открытый ключ, а полная пара - открытый и секретный ключи -нужна лишь отправителю. Поэтому подписывающая сторона создает объект RSACryptoServiceProvider и экспортирует затем только открытый ключ при помощи метода ExportParameters с параметром false.

private void buttonSign_Click(object sender, EventArgs e)

 {

//получить исходное сообщение в виде

//байтового массива

byte[] messagebytes = Encoding.UTF8.GetBytes(

    textOriginalMessage.Text);

 

//создать дайджест сообщения алгоритмом SHA1

SHA1 sha1 = new SHA1CryptoServiceProvider();

byte[] hashbytes =

    sha1.ComputeHash(messagebytes);

 

//отобразить дайджест сообщения

//в шестнадцатеричном формате

StringBuilder sb = new StringBuilder();

for (int i=0; i<hashbytes.Length; i++)

{

    sb.Append(String.Format(

        "{0,2:X2} ", hashbytes[i]));

    }

textMessageDigestSHA1.Text = sb.ToString();

 

//Создание объект RSA с ключом по умолчанию

RSACryptoServiceProvider rsa =

    new RSACryptoServiceProvider();

 

//создать хеш при помощи OID для алгоритма SHA-1

signaturebytes =

    rsa.SignHash(hashbytes, "1.3.14.3.2.26");

 

//извлечь параметры RSA, необходимые

//для верификации

rsaparams = rsa.ExportParameters(false);

 

//отобразить значение ЭЦП в

//шестнадцатеричном формате

sb = new StringBuilder();

for (int i=0; i<signaturebytes.Length; i++)

{

        sb.Append(String.Format(

    "{0,2:X2} ", signaturebytes[i]));

    }

textSignature.Text = sb.ToString();

 

//отобразить параметры RSA в

//шестнадцатеричном формате

for (int i=0; i<rsaparams.Modulus.Length; i++)

    {

sb.Append(String.Format(

    "{0,2:X2} ", rsaparams.Modulus[i]));

    }

textBoxModulus.Text = sb.ToString();

 

for (int i=0; i<rsaparams.Exponent.Length; i++)

{

        sb.Append(String.Format(

            "{0,2:X2} ", rsaparams.Exponent[i]));

    }

textBoxExponent.Text = sb.ToString();

 

//обработать пользовательский интерфейс

buttonSign.Enabled = false;

buttonVerify.Enabled = true;

buttonVerify.Select();

}

 

4. Событие Click кнопки buttonVerify

Метод buttonVerify_Click верифициру­ет цифровую подпись сообщения. Здесь заново вычисляется хеш сообще­ния, для того чтобы его можно было сравнить с подписью. Затем создается объект RSA, но на этот раз автоматически сгенерированный открытый ключ заменяется вызовом метода ImportParameters с использованием того объекта RSAParameters, что был создан ранее подписывающей процедурой. Благодаря этому параметры RSA будут идентичны параметрам, использован­ным при создании подписи.

private void buttonVerify_Click(object sender, EventArgs e)

{

//получить сообщение, возможно измененное

   // в виде байтового массива

   byte[] messagebytes = Encoding.UTF8.GetBytes(

     textOriginalMessage.Text);

 

   //создать дайджест исходного сообщения

//алгоритмом SHA1

   SHA1 sha1 = new SHA1CryptoServiceProvider();

   byte[] hashbytes =

      sha1.ComputeHash(messagebytes);

 

   //создать объект RSA с импортированными

//параметрами

   RSACryptoServiceProvider rsa =

       new RSACryptoServiceProvider();

   rsa.ImportParameters(rsaparams);

 

   //верифицировать хеш, используя идентификатор

//OID для SHA-1

   bool match = rsa.VerifyHash(

  hashbytes, "1.3.14.3.2.26", signaturebytes);

 

   //вывести сообщение с результатами верификации

   String strResult;

   if (match)

       strResult = "Верификация успешно пройдена";

   else

       strResult = "Верификация показала ошибку";

   MessageBox.Show(

     strResult,

       "Результат верификации",

        MessageBoxButtons.OK,

        MessageBoxIcon.Exclamation);

 

   //обработка пользовательского интерфейса

   buttonSign.Enabled = true;

   buttonVerify.Enabled = false;

   buttonVerify.Select();  }


Дата добавления: 2018-08-06; просмотров: 617; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!