RSA в качестве алгоритма цифровой подписи
Алгоритм RSA можно использовать, как для обеспечения секретности, так и для формирования ЭЦП.
С точки зрения цифровой подписи нет необходимости в шифровании сообщения целиком. Вполне достаточно сгенерировать хеш исходного сообщения и зашифровать этот небольшой по размеру объект своим секретным ключом. Любой, располагающий соответствующим открытым ключом (то есть, кто угодно), сможет расшифровать хеш и верифицировать его. Если дешифрованный хеш совпадет с вновь вычисленным хешем, получатель может увериться в том, что сообщение отправлено именно владельцем соответствующего секретного ключа и с момента наложения подписи никем не изменено. Уверенность эта проистекает из того обстоятельства, что крайне трудно подобрать второе сообщение, которое дало бы при вычислении точно такой же хеш.
Алгоритм цифровой подписи DSA
Алгоритм DSA является федеральным стандартом NIST, используемым совместно со стандартом SHA (Secure Hash Algorithm - хеширующий криптографический алгоритм). Институт NIST опубликовал первую версию алгоритма DSA, как составную часть стандарта DSS (Digital Signature Standard - Стандарт цифровой подписи, FIPS 186) в мае 1994 года. DSA основывается на задаче дискретных логарифмов.
Иерархия класса AsymmetricAlgorithm
Иерархия наследования класса асимметричного алгоритма, располагающаяся в пространстве имен System.Security.Cryptography, приведена на рисунке 4.1 (см. Лабораторную работу № 4). На рисунке не показано, что AsymmetricAlgorithm производится из класса Object. Класс AsymmetricAlgorithm является абстрактным классом, и из него производятся классы 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; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!