Класс SymmetricAlgorithm




Полковский Олег Александрович

ассистент инсти­тута физико-математических наук и информацион­ных технологий БФУ им. И. Канта

Место прохождения практики

БФУ им. И. Канта

лаборатория программно-аппаратных средств защиты ин­фор­мации (корпус №2, ауд. 101)

236016; г. Калининград, ул. А. Невского, 14

Плановая продолжительность практики
с 26 июня по 9 июля 2017 г.

Фактическая продолжительность практики
с 26 июня по 7 июля 2017 г.

О.Net Framework Cryptographic Model

.Net Framework Cryptographic Model – это набор классов, интерфейсов, а также их имплементации, помогающие решить две главных задачи криптографии – сохранение целостности данных и их конфиденциальности. Так как платформа.Net Framework рассчитана на поддержку объектно-ориентированных языков, то.Net Framework Cryptographic Model имеет собственную структуру, состоящую из трёх уровней:

· Тип алгоритма, задающийся одним из следующих абстрактных классов: SymmetricAlgorithm (для симметричного шифрования), AsymmetricAlgorithm (для асимметричного шифрования) или HashAlgorithm (для хеш-функций

· Абстрактный класс алгоритма, наследующий один из трёх классов с предыдущего уровня. Например, классы Aes, RC2, или ECDiffieHellman

· Собственно, имплементация класса из предыдущего уровня

Благодаря такой структуре можно быстро и удобно реализовать собственный вариант алгоритма, унаследовавшись от второго уровня, или даже от первого. Однако данная структура продиктована деталями реализации алгоритмов. Если же подойти к структуре с точки зрения криптографии, то.Net Framework Cryptographic Model состоит из следующих частей:

· Сохранение конфиденциальности данных:

o Класс Aes, наследующийся от SymmetricAlgorithm

o Класс DES, наследующийся от SymmetricAlgorithm

o Класс RC2, наследующийся от SymmetricAlgorithm

o Класс Rijndael, наследующийся от SymmetricAlgorithm

o Класс RSA, наследующийся от AsymmetricAlgorithm

· Сохранение целостности данных:

o Класс HMACSHA256, наследующийся от HashAlgorithm

o Класс HMACSHA512, наследующийся от HashAlgorithm

· Цифровая подпись

o Класс DSA, наследующийся от AsymmetricAlgorithm

o Класс ESDsa, наследующийся от AsymmetricAlgorithm

o Класс RSA, наследующийся от AsymmetricAlgorithm

· Обмен ключами:

o Класс ECDiffieHellman, наследующийся от AsymmetricAlgorithm

o Класс RSA, наследующийся от AsymmetricAlgorithm

· Генерация случайных чисел

o Класс RNGCryptoServiceProvider, наследующийся от Cryptography.RandomNumberGenerator

Как видно, в данной криптографической модели присутствуют криптосистемы с открытым (класс AsymmetricAlgorithm) и закрытым (класс SymmetricAlgorithm) ключами, причём большую поддержку получают именно симметричные (блочные) алгоритмы шифрования в силу их относительного быстродействия. Для создания сообщения с открытым ключам можно использовать класс RSA. Также предусмотрены классы для обмена ключами и генерации случайного числа.

Пространство имен Cryptography не только предоставляет алгоритмы шифрования, но и содержит дочернее пространство имен Х509Certificates, предоставляющее методы, помогающие использовать сертификаты X.509 v.3. - стандарт ITU-T для инфраструктуры открытого ключа, являющейся набором средств, распределённых служб и компонентов, в совокупности используемых для поддержки криптозадач на основе закрытого и открытого ключей.

Класс HashAlgorithm

Начнём рассмотрение внутреннего строения.Net Framework Cryptographic Model с класса HashAlgorithm, наследующего интерфейс System.Security.Cryptography.ICryptoTransform. Для начала рассмотрим сам интерфейс ICryptoTransform. Класс, наследующий данный интерфейс должен обладать следующими свойствами:

Имя Описание
CanReuseTransform Возвращает значение, указывающее, возможно ли повторное использование текущего преобразования.
CanTransformMultipleBlocks Возвращает значение, указывающее, возможно ли преобразование нескольких блоков.
InputBlockSize Возвращает размер входного блока.
OutputBlockSize Возвращает размер выходного блока.

 

и методами:

Имя Описание
Dispose() Выполняет определяемые приложением задачи, связанные с удалением, высвобождением или сбросом неуправляемых ресурсов.(Наследуется от IDisposable.)
TransformBlock(Byte[], Int32, Int32, Byte[], Int32) Преобразует заданную область входного массива байтов и копирует результирующее преобразование в заданную область выходного массива байтов.
TransformFinalBlock(Byte[], Int32, Int32) Преобразует заданную область заданного массива байтов.

 

В самом классе к свойствам прибавляются также:

Hash Возвращает значение вычисляемого хэш-кода.
HashSize Возвращает размер вычисляемого хэш-кода в битах.

Далее перечисляются методы, определённые в самом классе HashAlgorithm, не наследующиеся от класса object или интерфейса ICryptoTransform:

 

Имя Описание
Clear() Освобождает все ресурсы, используемые классом HashAlgorithm.
ComputeHash(Byte[]) Вычисляет хэш-значение для заданного массива байтов.
ComputeHash(Byte[], Int32, Int32) Вычисляет хэш-значение для заданной области заданного массива байтов.
ComputeHash(Stream) Вычисляет хэш-значение для заданного объекта Stream.
Create() Создает экземпляр реализации по умолчанию хэш-алгоритма.
Create(String) Создает экземпляр заданной реализации хэш-алгоритма.
HashCore(Byte[], Int32, Int32) Если переопределено в производном классе, передает данные, записанные в объект, на вход хэш-алгоритма для вычисления хэша.
HashFinal() Если переопределено в производном классе, завершает вычисление хэша после обработки последних данных криптографическим потоковым объектом.
Initialize() Инициализирует реализацию класса HashAlgorithm.
MemberwiseClone() Создает неполную копию текущего объекта Object.(Наследуется от Object.)
ToString() Возвращает строковое представление текущего объекта. (Наследуется от Object.)

 

Объявление нового экземпляра объекта HashAlgorithm и вычисление с его помощью хеша выполняется следующим образом:

HashAlgorithm sha = new SHA1CryptoServiceProvider();

byte[] result = sha.ComputeHash(dataArray);

 

Где метод ComputeHash получает на вход массив байт, для которого нужно посчитать хеш значение. Если вместо объекта класса SHA1CryptoServiceProvider создать объект какого-либо другого класса, наследующего прямого потомка HashAlgorithm (например, System.Security.Cryptography.SHA256.SHA256CryptoServiceProvider), то процесс получения соответствующего хеша выполняется аналогично вызовом ComputeHash.

Заметим, что класс HashAlgorithm имеет лишь один конструктор без аргументов, переписать который запрещено ввиду того, что он определён как protected.

Класс CryptoStream

Прежде чем ознакомиться с алгоритмами шифрования, следует ознакомиться с таким классом, как CryptoStream, который определяет поток, который в свою очередь связывает потоки данных с криптографическими преобразованиями. Данный класс наследует интерфейсы Stream и IDisposable. Суть этого класса в том, что современный подход к криптографии в.Net Framework использует потокоориентированный дизайн: любые объекты, реализующие этот класс могут быть объединены в цепочку любым объектом, реализующим класс Stream, в результате чего отсутствует необходимость в буфере – данные, возвращаемые одним объектом сразу же подаются на вход следующему. Всё вышеперечисленное уменьшает вероятность утечки данных из промежуточного буфера и снижает количество памяти, требуемое для работы программы.

Класс SymmetricAlgorithm

Класс SymmetricAlgorithm реализует процесс блочного шифрования. Это абстрактный базовый класс, от которого наследуются все реализации симметричных алгоритмов шифрования. Он наследует интерфейс IDisposable. Данный класс имеет конструктор по умолчанию – SymmetricAlgorithm().

Рассмотрим внутренее строение этого класса. В дальнейшей таблице приведены свойства SymmetricAlgorithm:

Имя Описание
BlockSize Возвращает или задает размер блока криптографической операции (в битах).
FeedbackSize Возвращает или задает размер ответа в криптографической операции (в битах). Нужен для формирования ключей с последующих раундах.
IV Возвращает или задает вектор инициализации (IV) для симметричного алгоритма.
Key Возвращает или задает секретный ключ для симметричного алгоритма.
KeySize Возвращает или задает размер секретного ключа (в битах), используемого симметричным алгоритмом.
LegalBlockSizes Возвращает размеры блоков (в битах), которые поддерживаются симметричным алгоритмом.
LegalKeySizes Возвращает размеры ключа (в битах), которые поддерживаются симметричным алгоритмом.
Mode Возвращает или задает режим функционирования симметричного алгоритма.
Padding Возвращает или задает режим заполнения, используемый в симметричном алгоритме.

 

Прежде чем продолжить рассмотрение, остановимся поподробнее на таких свойствах, как IV и Key. По сути дела они оба являются ключами шифровки/дешифровки и для восстановления информации из шифротекста оба значения должны совпадать с использованными при шифровки открытого текста.

Рассмотрим теперь методы, кроме наследующихся от Object:

 

Имя Описание
Clear() Освобождает все ресурсы, используемые классом SymmetricAlgorithm.
Create() Создает криптографический объект по умолчанию, используемый для выполнения симметричного алгоритма.
Create(String) Создает заданный криптографический объект, используемый для выполнения симметричного алгоритма.
CreateDecryptor() Создает симметричный объект-дешифратор с текущим свойством Key и вектором инициализации (IV).
CreateDecryptor(Byte[], Byte[]) При переопределении в производном классе создает симметричный объект-дешифратор с указанным свойством Key и вектором инициализации (IV).
CreateEncryptor() Создает симметричный объект-шифратор с текущим свойством Key и вектором инициализации (IV).
CreateEncryptor(Byte[], Byte[]) Если переопределено в производном классе, создает симметричный объект-шифратор с заданным свойством Key и вектором инициализации (IV).
Dispose() Освобождает все ресурсы, используемые текущим экземпляром класса SymmetricAlgorithm.
Dispose(Boolean) Освобождает неуправляемые ресурсы, используемые объектом SymmetricAlgorithm, а при необходимости освобождает также управляемые ресурсы.
GenerateIV() Если переопределено в производном классе, создает произвольный вектор инициализации (IV), используемый для алгоритма.
GenerateKey() Если переопределено в производном классе, генерирует произвольный ключ (Key), используемый для алгоритма.
ValidKeySize(Int32) Определяет допустимость указанного размера ключа для текущего алгоритма.

 

Отдельно отметим методы CreateDecryptor(Byte[], Byte[]) и CreateEncryptor(Byte[], Byte[]), которые возвращают объект-дешифратор(шифратор), наследующий ICryptoTransform. Затем для процесса шифровки/дешифровки информации программисту остаётся всего лишь создать CryptoStream, воспользовавшись соответствующим конструктором, что и будет рассмотрено в примере кода далее.

Поля данного класса непосредственно с окружающим кодом не взаимодействуют, поэтому их рассмотрение здесь можно опустить.

Рассмотрим теперь, как реализуется процесс криптографического преобразования на практике. Нижеизложенный код считывает заданный файл на диске (1.txt), шифрует его и записывает в следующий (2.bin), затем считывает его, расшифровывает и записывает в третий (3.txt):

using System;

using System.IO;

using System.Security.Cryptography;

using System.Collections.Generic;

using System.Text;

using System.Threading.Tasks;

 

namespace Encrypt_Decrypt

{

class Program

{

static void Main(string[] args)

{

CypherDemonstration test = new CypherDemonstration();

string file1_Path = @"D:/Alex/1.txt"; //исходный текст

string file2_Path = @"D:/Alex/2.bin"; //шифротекст

string file3_Path = @"D:/Alex/3.txt"; //расшифрованный текст

test.EncryptData(file1_Path,file2_Path);

test.DecryptData(file2_Path, file3_Path);

Console.ReadKey();

}

}

 

public class CypherDemonstration

{

public byte[] rijnKey;

public byte[] rijnIV;

 

public CypherDemonstration()

{

SymmetricAlgorithm Key_and_IV_Generator = SymmetricAlgorithm.Create();

this.rijnKey = Key_and_IV_Generator.Key;

this.rijnIV = Key_and_IV_Generator.IV;

}

 

public void EncryptData(String inName, String outName)

{

//Создаём потоки записи файла на диск

FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);

FileStream fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);

fout.SetLength(0);

 

//Необходимые для процесса чтения/записи переменные

byte[] bin = new byte[127]; //промежуточный буфер для хранения результатов

long rdlen = 0; //Количество записанных байт

long totlen = fin.Length; //Итоговая длина записанного файла

int len; //Количество уже записанных байт

 

SymmetricAlgorithm rijn = SymmetricAlgorithm.Create(); //Создаём имплементацию RijndaelManaged по умолчанию.

CryptoStream encStream = new CryptoStream(fout, rijn.CreateEncryptor(rijnKey, rijnIV), CryptoStreamMode.Write);

 

Console.WriteLine("Encrypting...");

 

//Считываем из входного файла, шифруем и записываем в выходной

while (rdlen < totlen)

{

len = fin.Read(bin, 0, 127);

encStream.Write(bin, 0, len);

rdlen = rdlen + len;

Console.WriteLine("{0} bytes processed", rdlen);

}

 

encStream.Close();

fout.Close();

fin.Close();

}

 

public void DecryptData(String inName, String outName)

{

FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);

FileStream fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);

fout.SetLength(0);

 

byte[] bin = new byte[127];

long rdlen = 0;

long totlen = fin.Length;

int len;

 

SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();

rijn.Key = this.rijnKey; //Передаём объекту rijn ключ и IV для дальнейшей расифровки

rijn.IV = this.rijnIV;

CryptoStream decStream = new CryptoStream(fout, rijn.CreateDecryptor(), CryptoStreamMode.Write);

 

while (rdlen < totlen)

{

len = fin.Read(bin, 0, 127);

decStream.Write(bin, 0, len);

rdlen = rdlen + len;

Console.WriteLine("{0} bytes processed", rdlen);

}

}

}

}



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-07-25 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: