Программирование асимметричных шифров

advertisement
Программирование при
помощи .NET Asymmetric
Cryptography
Пространство имен
System.Security.Cryptography


Для иллюстрации этой темы мы
рассмотрим примеры программ
RSAAIgorithm и SavingKeysAsXml.
Эти два образца кода покажут, как следует
шифровать и дешифровать при помощи
алгоритма RSA, а также как сохранять и
извлекать информацию о ключах в
формате XML.
Пример использования алгоритма RSA
Пример RSAAIgorithm
использует конкретный
класс
RSACryptoServiceProvider,
принадлежащий
абстрактному классу
AsymmetricAIgorithm.
Пример программы “RSAAIgorithm”




Программа предназначена для шифрования и
дешифрования сообщений.
Вы можете ввести текст сообщения в текстовое поле в
верхней части формы.
После этого, щелчком на кнопке Encrypt, вы зашифруете
сообщение и заполните все поля формы кроме последнего
поля (в остальных полях появятся параметры RSA).
Наконец, щелчок на кнопке Decrypt расшифрует дaнные,
которые отобразятся в самом нижнем поле.
Разумеется, расшифрованное сообщение окажется
идентичным исходному открытому тексту.
Скрин-шот программы
RSAAlgorithm
Исходный код программы
RSAAIgorithm


Пара ключей генерируется программой при запуске
автоматически, но можно сгенерировать новую пару нажав на
кнопку New RSA Parametrs, которая вызывает функцию
GenerateNewPArams.
Впервые эта функция вызывается и генерирует новые ключи при
запуске формы.
private void GenerateNewRSAParams()
{
//установить ассиметричный алгоритм RSA
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//извлечь открытые и секретные параметры RSA
rsaParamsIncludePrivate = rsa.ExportParameters(true);
// извлечь только открытыe параметры RSA
rsaParamsExcludePrivate = rsa.ExportParameters(false);
…
}
void GenerateNewRSAParams()

Этот метод создает объект класса RSACryptoServiceProvider
извлекает его внешние и внутренние параметры с помощью метода
ExportParametrs RSA класса и отображает эти параметры в
пользовательском интерфейсе. Фактически эти параметры хранятся
в полях типа RSAParametrs.
//необходимые для шифрования
RSAParameters rsaParamsExcludePrivate;
//открытые и секретные параметры RSA для дешифрования
RSAParameters rsaParamslncludePrivate;

Поле этого типа с именем rsaParamsExcludePrivate содержит
значения открытых параметров, которые необходимы для
шифрования, выполняемого методом buttonEncript_Click. Поле
этого типа с именем rsaParamsIncludePrivate содержит значения
открытых и секретных параметров, которые необходимы для
дешифрования методом buttonDecript_Click.


Метод ExportParameters здесь
вызывается дважды. Первый раз методу
задается аргумент True, а во второй
False.
Значение True указывает методу, что в
информацию необходимо включить все, в
том числе секретный ключ.
При вызове с аргyментом False метод
экспортирует только информацию,
относящуюся к открытому ключу.
void buttonEncrypt_Click( object
sender, System.EventArgs е)
В методе buttonEncrypt_Click создается новый экземпляр класса
RSACryptoServiceProvider, инициализируя eгo сохраненной
информацией открытогo ключа при помощи метода
ImportParameters объекта RSA (при этом в качестве aргументa
используя поле rsaParamsExcludePrivate). Далее мы получаем
открытый текст в виде байтового массива с
именем plainbytes.
private void buttonEncrypt_Click( object sender, System.EventArgs е)
{
//работаем с пользовательским интерфейсом
….
//установить асимметричный алгоритм RSA
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
// извлечь только открытые пaраметры RSA дли шифрования
rsa.lmportparameters(rsaParamsExcludePrivate);
//прочитать открытый текст и зашифровать eгo
byte [] plainbytes = Encoding.UTF8.Getвytes(textplaintext.Text);
Далее выполняется главное действие, вызывая метод Encrypt
объекта RSA. Этот вызов возвращает байтовый массив
с именем cipherbytes. Это не локальная переменная, а свойство
конкретного экземпляра объекта, поскольку нам потребуется
передать этот массив методу, выполняющему дешифрование.
cipherbytes = rsa.Encrypt(plainbytes, false); // использование fOAEP требует
// пaкета шифрованиия
//отобразить зашифрованный текст
….
// Отобразить зашифрованный текст
….
//в шестнадцатеричном формате
….
//работаем с пользовательским интерфейсом
….
}
Метод Encrypt()


Пример RSAAIgorithm использует метод Encrypt класса
RSACryptoServiceProvider. Этот метод получает на входе два
параметра,
первый из которых должен представлять собой байтовый
массив, содержащий входные данные.
Второй параметр, булево значение, должен указывать
на режим дополнения, который должен использовать метод.
Дополнение требуется потому, что алгоритм требует
фиксированного размера блока входных данных. Для
достижения этого размера необходимо будет дополнять
реальные данные.


Если второму параметру присвоено значение
True, то для дополнения будет использоваться
технология ОАЕP.
В противном случае используется традиционный
режим дополнения PKCS#1 vl.5.
Метод Encrypt возвращает результирующие
зашифрованные данные в виде байтового
массива.
void buttonDecrypt_Click (object
sender, System.EventArgs е)
Метод buttonDecrypt_Click вызывается по щелчку
пользователя на кнопке Decrypt. Снова, точно так же,
создается объект RSA. Информация в этот объект
загружается при помощи eгo метода ImportParameters,
однако на этот раз apгyмeнтoм служит поле
rsaParamsIncludePrivate, поскольку для дешифрования
необходим как открытый, так и секретный ключи.
private void buttonDecrypt_Click (object sender, System.EventArgs е)
{
//Установить асимметpичный алгоритм RSA
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
/ /импортировать открытый и секретный ключи
rsa.Importparameters(rsaparamslncludePrivate);
Метод Decrypt()
Открытый текст мы получаем обращением к методу Decrypt
объекта RSA. Первый параметр байтовый массив, содержащий
зашифрованные данные. Второй параметр имеет точно такой же
смысл, что и в методе Encrypt. Возвращаемое значение
представляет собой байтовый массив с расшифрованными
данными.
Поскольку для шифрования и дешифрования использовались
ключи RSA, принадлежащие к одной паре, результирующий
дешифрованный текст в точности совпадет с исходным.
//прочитать зашифровaнный текст и дешифровать eгo
byte [] plainbytes = rsa.Decrypt( cipherbytes, false); // отобразить полученный
открытый текст
….
//работаем с пользовательским интерфейсом
….
}
Сохранение ключей в
формате XML
Не всегда возможно передать содержимое
объекта ExportParameters нa прямую
между двумя приложениями, тем более,
если речь идет о разных платформах или
хотя бы о разных криптоrрафических
библиотеках.
Более удобный и универсальный способ
передачи открытого ключа заключается в
использовании ХМL-потока.
Пример программы
SavingKeysAsXml


Этот пример почти идентичен предыдущей
программе.
Главное отличие состоит в том, что для
хранения и передачи открытогo ключа между
методом шифрования и методом
дешифрования мы используем XML вместо
объекта ExportParameters.
Еще одно отличие заключается в том, что
информация о параметрах RSA не
отображается, а вместо этого отображается
содержимое ХМL потока.
Наиболее серьезные изменения по отношению к
предыдущей программе заключаются в том, что
вызовы методов ExportParameters и
ImportParameters класса
RSACryptoServiceProvider заменены вызовами
методов ToXmlString и FromXmlString,
принадлежащих тому же классу. Здесь также
используется логический apгумент,
указывающий, нужно ли включать в информацию
секретный ключ.
void GenerateNewRSAParams()
private void GenerateNewRSAParams()
{
//установить асимметричный алгоритм RSA
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
/ /Открытый и секретный ключи RSA
StreamWriter writer = new StreamWriter("PublicPrivateKey.xml");
string publicPrivateKeyXМL = rsa.ToXmlString(true);
writer.Write(publicPrivateKeyXМL);
writer.Close() ;
//только открытый ключ RSA
writer = new StreamWriter("PublicOnlyKey.xml");
string publicOnlyKeyXМL = rsa.ToXmlString(false);
writer.Write(publicOnlyKeyXМL);
writer.Close();
//отобразить оба ключа RSA
textвoxPublicKeyXМL.Text = publicPrivateKeyXМL;
//работаем с пользовательским интерфейсом
…
}
void buttonDecrypt_Click(object sender,
System.EventArgs е)
private void buttOnDecrypt_Click(object sender, System.EventArgs е)
{
//установить асимметричный алrоритм RSA
//при помощи ключа из XМL файла
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
/ /открытый и секретный пaраметры RSA для дешифрования
StreamReader reader = new StreamReader("PublicPrivateKey.xml");
string publicPrivateKeyXМL = reader.ReadToEnd();
rsa.FromXmlString(PublicPrivateKeyXМL);
reader.Close();
//прочитать шифрованный текст и дешифровать eгo
byte [] plainbytes = rsa.Decrypt( cipherbytes, false);
//отобразить полученный открытый текст
…
//работаем с пользовательским интерфейсом
…
}
Скрин-шот программы
SavingKeysAsXml
Download