Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Лабораторная работа № 4
Шифрование данных в .NET Framework
Цель работы: изучение криптографической системы .NET
Теоретические сведения
Шифрование с симметричным ключом
Шифрование с симметричным ключом, также известное как шифрование с секретным ключом криптографический прием, в котором используется один секретный ключ как для шифрования, так и для расшифровки данных.
Алгоритмы шифрования с симметричным ключом обрабатывают открытый текст при помощи секретного ключа шифрования, чтобы создать зашифрованный текст. Зашифрованный текст нельзя расшифровать, чтобы получить простой текст, если не иметь секретного ключа.
Симметричные алгоритмы работают очень быстро и хорошо подходят для шифрования больших объемов данных.
Но, несмотря на то, что симметричное шифрование обеспечивает определенный уровень защиты, злоумышленник может получить из шифрованного текста открытый текст, если имеет достаточно времени. Время, необходимое для дешифрования текста зависит от применяемого алгоритма шифрования.
Недостатком шифрования с секретным ключом является то, что оно предполагает, что стороны уже договорились о том, какой ключ будет использоваться. Сам секретный ключ в свою очередь нуждается в защите. Поэтому для обмена ключами пользователи должны использовать какой-то защищенный способ. После того, как стороны договорятся о ключе, они смогут свободно передавать друг другу шифрованные данные. Однако ключи следует регулярно менять по той же причине, по которой нужно регулярно менять пароли.
Необходимость использования общего секрета делает невозможным применение симметричного шифрования для защиты произвольных, неподготовленных сетевых взаимодействий.
Классы симметричных алгоритмов в .NET Framework
Большинство криптографических функций .NET Framework встроено в пространство имен System.Security.Cryptography, включая четыре реализации алгоритмов симметричного шифрования.
Таблица. Классы для работы с асимметричными алгоритмами
Класс |
Длина ключа |
Описание |
SymmetricAlgorithm |
He определена |
Базовый класс, от которого производны все симметричные алгоритмы |
RijndaelManaged |
128-256 бит с 32-битовым приращением |
Реализация алгоритма симметричного шифрования Rijndael в .NET Framework. Этот алгоритм является стандартом шифрования, принятым правительством США, и известен также как AES (Advanced Encryption Standard). Класс RijndaelManaged единственный полностью управляемый класс алгоритмов симметричного шифрования в .NET Framework. Все остальные классы алгоритмов шифрования вызывают неуправляемый код. Поэтому класс RijndaelManaged является предпочтительным выбором, если приложение будет работать в среде с частичным доверием |
DES |
56 битов |
Data Encryption Standard (DES) алгоритм симметричного шифрования, использующий относительно короткие ключи, уязвимые к атаке перебором, из-за чего следует избегать его использования. Однако этот алгоритм до сих пор часто используется, так как совместим со многими устаревшими платформами. |
TripleDES |
156 битов, из которых для шифрования используется только 112 |
Реализация алгоритма симметричного шифрования Triple DES (3DES) в .NET Framework. По сути, этот алгоритм применяет алгоритм DES три раза |
Все классы симметричных алгоритмов производны от базового класса System.Security.Cryptography.SymmetricAlgorithm и имеют следующие общие свойства:
Кроме того, классы симметричных алгоритмов имеют одинаковые методы:
Все алгоритмы симметричного шифрования, включенные в .NET Framework, являются алгоритмами блочного шифрования, разделяющими данные на части, шифрующиеся по отдельности. Второй блок шифруется при помощи результатов шифрования первого блока, третий при помощи результатов второго и т. д. Однако первый блок не имеет предыдущего блока, поэтому вместо него алгоритм шифрования использует вектор инициализации.
Классы .NET Framework позволяют обрабатывать только 64-разрядные числа, поэтому ключи можно отображать двумя способами: в виде шестнадцатеричных чисел и в кодировке Base64.
SymmetricAlgorithm myAlg = new RijndaelManaged();
foreach (byte thisByte in myAlg.Key)
Console.Write(thisByte.ToString("X"));
SyrnmetricAlgorithm myAlg = new RijndaelManaged();
Console.WriteLine(Convert.ToBase64String(myAlg.Key));
Для создания криптографически случайных чисел. Нужно использовать класс System.Security.Cryptography.RNGCryptoServiceProvider. Класс RNGCryptoServiceProvider генерирует случайные значения при вызове метода GetBytes. При этом создаются только массивы случайных байтов, поэтому нужно самостоятельно преобразовывать случайные байты в значения нужного формата. Для этого можно воспользоваться классом System.BitConverter, который включает методы преобразования случайных байтов во все распространенные числовые классы. Приведенный фрагмент кода консольного приложения генерирует случайное значение и преобразовывает его в 64-разрядное целое число без знака и число с плавающей запятой:
RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
byte[] randValue = new byte[256];
rand.GetBytes(randValue);
Consols.WriteLine(System.BitConverter.ToUInt64(randValue, 0));
Console.WriteLine(System.BitConverter.ToDouble(randValue, 0));
Если задача передачи секретного ключа лежит на пользователях, генерируйте ключи симметричного шифрования на основе паролей. Однако пароль проще подобрать, чем обычный ключ. Кроме того, многие пароли не являются случайными, так что злоумышленник может сократить время взлома, используя словари паролей. Нельзя использовать в качестве ключей шифрования непосредственно пароли, но можно преобразовать пароль в ключ, используя класс System.Security.Cryptography.PasswordDeriveBytes.
Класс PasswordDeriveBytes, кроме пароля пользователя, принимает три значения: случайное значение, присоединяемое к паролю, название применяемого хэш алгоритма и число итераций для операции создания ключа. В идеале, все три значения должны быть случайными. Изменение этих значении приводит к генерации другого ключа, поэтому шифратор и дешифратор должны использовать одинаковые значения.
public PasswordDeriveBytes(string strPassword, byte[] rgbSalt, string strHashName, int Iterations);
После инициализации можно получить ключ, вызвав метод PasswordDeriveBytes.GetBytes. Метод GetBytes принимает число байтов, которое нужно вернуть. При получении ключа нужно определить длину, исходя из числа битов, требуемого свойствами KeySize и Blocksize объекта алгоритма. Кроме ключа, алгоритм шифрования использует вектор инициализации, который нужно указать как для шифратора, так и для дешифратора. Тогда как длина генерируемого ключа определяется на основе свойства KeySize, длина вектора инициализации должна определяться на основе свойства Blocksize алгоритма шифрования.
В следующем примере создается ключ и вектор инициализации для ранее созданного объекта симметричного алгоритма myAlg при помощи ранее заданной строки password. В этом фрагменте кода используются статическое значение, добавляемое к паролю, и статическое число итераций.
byte[] saltValueBytes = Encoding.ASCII.GetBytes("This is my salt");
PasswordDeriveBytes passwordKey = new PasswordDeriveBytes(password, saltValueBytes, "SHA1", 3);
myAlg.Key = passwordKey.GetBytes(myAlg.KeySize/8);
myAlg.IV = passwordKey.GetBytes(myAlg.BlockSize/8);
Шифрование и расшифровка сообщений
Чтобы зашифровать или расшифровать сообщение выполните следующее:
1. Создайте объект Stream для обращения к файлу или памяти откуда нужно считать или записать данные.
2. Создайте объект SymmetricAlgorithm.
3. Укажите ключ и вектор инициализации.
4. Вызовите метод SymmetricAlgorithm.CreateEncryptor() или SymmetricAlgorithm.CreateDecryptor(), чтобы создать объект ICryptoTransform.
5. Создайте объект CryptoStream, используя объекты Stream и ICryptoTransform.
6. Прочитайте или запишите данные в объект CryptoStream, как в любой другой объект Stream.
Следующее консольное приложение считывает нешифрованный файл, шифрует его и сохраняет результат как новый файл. Это приложение принимает 2 аргумента: имя нешифрованного файла и имя файла, который будет создан при шифровании. Показан только метод Main, но приложение использует пространства имен System.IO System.Security.Cryptography.
string unencryptedFileName = args[0];
string encryptedFileName = args[1];
//Шаг 1: Создаем объекты Stream
FileStream unencryptedFile = new FileStream(unencryptedFileName, FileMode.Open, FileAccess.Read);
FileStream encryptedFile = new FileStream(encryptedFileName, FileMode.OpenOrCreate, FileAccess.Write);
//Шаг 2: Создаем объект SymmetricAlgorithm
SymmetricAlgorithm myAlg = new RijndaelManaged();
//Шаг 3 (необязательный): Указываем ключ
myAlg.GenerateKey();
//Считываем нешифрованный файл в fileData
byte[] fileData = new byte [unencryptedFile.Length];
unencryptedFile.Read(fileData, 0, (int)unencryptedFile.Length);
//Шаг 4: Создаем объект ICryptoTransform
ICryptoTransform encryptor = myAlg.CreateEncryptor();
//Шаг 5: Создаем объект CryptoStream
CryptoStream encryptStream = new CryptoStream(encryptedFile, encryptor, CryptoStreamMode.Write);
//Шаг 6: Записываем содержимое в объект CryptoStream
encryptStream.Write (fileData, 0, (int)unencryptedFile.Length);
//Закрываем файлы
encryptStream.Close();
unencryptedFile.Close();
encryptedFile.Close();
Асимметричное шифрование
Асимметричное шифрование, также известное как шифрование с открытым ключом криптографический прием, в котором для шифрования и расшифровки используются два разных ключа, открытый и закрытый. Для шифрования используется открытый ключ, который можно передавать кому угодно, а для расшифрования закрытый ключ, который должен храниться в тайне от неавторизованных пользователей. Открытый и закрытый ключи математически связаны. Данные, зашифрованные открытым ключом, можно расшифровать только при помощи закрытого ключа. Открытый ключ можно сделать доступным всем пользователям, он используется для шифрования данных, которые будут отправляться владельцу закрытого ключа.
Процесс асимметричного шифрования начинается с передачи открытого ключа. Обычно открытый ключ передается и сервером, и клиентом. Но если шифроваться должны данные, отправляемые только одной стороной, открытый ключ должна передавать только эта сторона.
После обмена открытыми ключами передаваемые данные шифруются при помощи открытого ключа получателя. Расшифровать эти данные сможет владелец закрытого ключа, соответствующего открытому ключу, который использовался для шифрования.
Асимметричные алгоритмы работают не так быстро, как симметричные. Асимметричные алгоритмы не очень хорошо подходят для шифрования больших объемов данных из-за снижения производительности. Одним из распространенных применений асимметричных алгоритмов является шифрование симметричного ключа и вектора инициализации перед передачей. Затем алгоритм симметричного шифрования используется для обработки всех передаваемых сообщений.
Классы ассиметричных алгоритмов в .NET Framework
В .NET Framework есть 2 класса для работы с ассиметричным шифрованием, и оба они основаны на классе System.Security.Cryptography.AsymmetricAlgorithm. Базовый класс имеет следующие свойства, некоторые из которых идентичны свойствам класса SymmetricAlgorithm:
В отличие от базового класса SymmetricAlgorithm, класс AsymmetricAlgorithm не имеет полезных методов. Вместо этого функциональность шифрования встраивается в объекты, реализующие класс AsymmetricAlgorithm. .NET Framework предоставляет две реализации этого класса:
В дополнение к свойствам класса AsymmetricAlgorithm, класс RSACryptoServiceProvider имеет следующие свойства:
Конструкторы по умолчанию всегда присваивают параметрам алгоритма наиболее строгие параметры, доступные в исполняющей среде, чтобы получить самый надежный вариант алгоритма из допустимых, не требуя от разработчика изменять какие-либо параметры.
Класс RSACryptoServiceProvider также имеет методы шифрования и расшифровки, а также для импорта и экспорта ключей:
Экспорт и импорт асимметричных ключей и пар ключей
Ключи RSA намного более сложны, чем ключи симметричного шифрования. Ключи RSA называются параметрами и представлены структурой RSAParameters. В таблице перечислены наиболее важные члены этой структуры и их предназначение. Структура включает несколько параметров, которые в таблице не приведены и к которым не нужно обращаться напрямую: DP, DQ, InverseQ, P И Q.
Таблица. Члены структуры RSAParameters
Параметр |
Описание |
D |
Закрытый ключ |
Exponent |
Короткая часть открытого ключа. Сокращенное обозначение e |
Modulus |
Длинная часть открытого ключа. Сокращенное обозначение n |
Почти всегда нужно экспортировать открытый ключ, так как без этого ключа никто не сможет отправлять владельцу закрытого ключа зашифрованные данные. Чтобы экспортировать открытый ключ в экземпляр структуры RSAParameters, используйте метод RSACryptoServiceProvider.ExportParameters, передав ему значение false.
В следующем примере продемонстрировано, как можно создать экземпляр алгоритма RSA и экспортировать его автоматически сгенерированный открытый ключ в объект RSAParameters с именем publicKey.
//Создаем экземпляр объекта алгоритма RSA
RSACryptoServiceProvider myRSA = new RSACryptoServiceProvider();
//Создаем объект RSAParameters, содержащий только открытый ключ
RSAParameters publicKey = myRSA.ExportParameters(false);
Чтобы поместить закрытые ключи в хранилище, выполните следующее:
1. Создайте объект CspParameters.
2. Укажите свойство CspParameters.KeyContainerName.
3. Создайте объект RSACryptoServiceProvider, используя перегруженный конструктор, принимающий объект CspParameters.
4. Присвойте свойству RSACryptoServiceProvider.PersistKeyInCsp значение true.
Шифрование и расшифровка сообщений при помощи асимметричных ключей
Чтобы шифровать и расшифровывать сообщения при помощи асимметричных ключей, вызовите методы RSACryptoServiceProvider.Encrypt и RSACryptoServiceProvider.Decrypt. Оба метода принимают два параметра:
Заполнение данных
Заполнение данных криптографический прием, используемый в асимметричных алгоритмах для защиты от атак, рассчитанных на то, что шифруется простой текст. .NET Framework поддерживает две схемы заполнения для алгоритма RSA:
Обычно следует использовать ОАЕР, так как это более новая и более безопасная схема по сравнению с PKCS. PKCS используйте только в том случае, если нужно взаимодействовать с устаревшими клиентскими системами, не поддерживающими ОАЕР. Поддержка ОАЕР отсутствует во всех операционных системах, выпущенных до Windows XP, включая Windows 2000.
Самый сложный момент в шифровании преобразование данных в формат байтового массива. Чтобы преобразовать строки в массивы байтов, используйте методы System.Text.Encoding.Unicode.GetBytes и System.Text.Encoding.Unicode.GetString. Например, следующее консольное приложение шифрует строку, используя заполнение данных PKCS#l v 1.5, а затем сразу же расшифровывает строку и выводит ее на экран:
string messageString = "Hello, World!";
RSACryptoServiceProvider myRsa = new RSACryptoServiceProvider();
Byte[] messageBytes = Encoding.Unicode.GetBytes(messageString);
Byte[] encryptedMessage = myRsa.Encrypt(messageBytes, false);
Byte[] decryptedBytes = myRsa.Decrypt(encryptedMessage, false);
Console.WriteLine(Encoding.Unicode GetString(decryptedBytes);
Контрольные вопросы
1. Поясните понятие шифрования с симметричным ключом.
2. Опишите классы симметричных алгоритмов в .NET.
3. Опишите свойства класса SymmetricAlgorithm.
4. Опишите методы класса SymmetricAlgorithm.
5. Опишите создание криптографически случайных чисел.
6. Поясните понятие ассиметричного шифрования.
7. Опишите свойства базового класса ассимметричного алгоритмов в .NET.
8. Опишите реализации базового класса ассиметричного шифрования и их дополнительные свойства.
9. Опишите методы класса RSACryptoServiceProvider.
10. Опишите экспорт и импорт ассиметричных ключей.
11. Поясните понятие заполнения данных.
Практическое задание
1. Задать пароль.
2. Сгенерировать пару ассиметричных ключей.
3. Зашифровать пароль алгоритмом RSA.
4. Расшифровать пароль.
5. Сгенерировать на основе пароля симметричный ключ шифрования.
6. Зашифровать файл указанным алгоритмом.
7. Расшифровать зашифрованный файл.
Варианты симметричных алгоритмов
Вариант |
Алгоритм |
1 |
Rijndael |
2 |
DES |
3 |
3DES |