// определение режима блочного шифрования

rc2CSP. Mode = CipherMode. CFB;

// создание объекта для параметров разрешенной длины ключа

KeySizes[] ks = rc2CSP. LegalKeySizes;

// максимально возможная для выбора длина ключа

KeyLen. Maximum = ks[0].MaxSize;

// минимально возможная длина ключа

KeyLen. Minimum = ks[0].MinSize;

// длина ключа по умолчанию

KeyLen. Value = rc2CSP. KeySize;

// шаг изменения длины ключа

KeyLen. Increment = ks[0].SkipSize;

/* запрещение прямого ввода длины ключа (возможно ее изменение только с помощью кнопок) */

KeyLen. ReadOnly = true;

}

// обработка нажатия кнопки "Выход"

private void Exit_Click(object sender, EventArgs e)

{

// закрытие главного окна

Close();

}

// обработка нажатия кнопки "Выбор файла"

private void Browse_Click(object sender, EventArgs e)

{

// создание объекта класса для диалога открытия файла

OpenFileDialog openFileDialog1 = new OpenFileDialog();

// определение свойств диалогового окна

// маска имени для отображаемых в окне файлов

openFileDialog1.Filter = "Все файлы (*.*)|*.*";

/* автоматическая проверка существования файла с введенным пользователем именем до закрытия диалога */

openFileDialog1.CheckFileExists = true;

// выбор в качестве начальной папки текущую

openFileDialog1.InitialDirectory = Directory. GetCurrentDirectory();

// восстановление текущей папки после закрытия диалога

openFileDialog1.RestoreDirectory = true;

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

if (openFileDialog1.ShowDialog() == DialogResult. OK)

НЕ нашли? Не то? Что вы ищете?

// сохранение и отображение имени выбранного файла

InputFName. Text = openFileDialog1.FileName;

}

// обработка нажатия кнопки "Зашифровать"

private void Encrypt_Click(object sender, EventArgs e)

{

/* признаки наличия в парольной фразе прописных и строчных букв, цифр и математических символов */

bool UpLetter=false, DownLetter=false, Digit=false, Math=false;

try

{

// проверка совпадения парольной фразы и ее подтверждения

if (PassFrase1.Text!= PassFrase2.Text)

throw ex = new ArgumentException("Парольная фраза и ее подтверждение не совпадают.");

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

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

{

// проверка очередного символа парольной фразы

UpLetter |= Char. IsUpper(PassFrase1.Text[i]);

DownLetter |= Char. IsLower(PassFrase1.Text[i]);

Digit |= Char. IsDigit(PassFrase1.Text[i]);

Math |= Char. IsSymbol(PassFrase1.Text[i]);

}

// проверка наличия всех четырех групп символов

if (!UpLetter || !DownLetter || !Digit || !Math)

throw ex = new ArgumentException("Парольная фраза не соответствует условиям сложности.");

// проверка длины парольной фразы

if (PassFrase1.Text. Length < 8)

throw ex = new ArgumentException("Парольная фраза короче требуемой длины.");

// создание объекта для генерации случайной примеси

RNGCryptoServiceProvider rand =

new RNGCryptoServiceProvider();

// создание буфера для случайной примеси

randBytes = new byte[8];

// получение примеси для секретного ключа

rand. GetBytes(randBytes);

// декодирование парольной фразы

byte[] pwd = Encoding. Unicode. GetBytes(PassFrase1.Text);

// создание объекта для генерации ключа из парольной фразы

pdb = new PasswordDeriveBytes(pwd, randBytes);

// генерация ключа

rc2CSP. Key = pdb. CryptDeriveKey("RC2", "MD5",

(int)KeyLen. Value, IV);

// создание объекта шифрования

ICryptoTransform encryptor =

rc2CSP. CreateEncryptor(rc2CSP. Key, IV);

/* отображение имени зашифрованного файла (к имени исходного файла добавляется расширение. enc) */

OutputFName. Text = InputFName. Text + ".enc";

// создание объектов для файловых потоков

finStream = new FileStream(InputFName. Text, FileMode. Open);

foutStream = new FileStream(OutputFName. Text, FileMode. Create);

// запись в начало результирующего файла случайной примеси

foutStream. Write(randBytes, 0, 8);

// создание объекта для потока шифрования

CrStream = new CryptoStream(foutStream, encryptor,

CryptoStreamMode. Write);

// выделение памяти для буфера ввода-вывода

bytes = new byte[finStream. Length];

// задание количества непрочитанных байт

numBytesToRead = (int)finStream. Length;

// ввод данных из исходного файла

int n = finStream. Read(bytes, 0, numBytesToRead);

// сохранение фактического количества прочитанных байт

numBytesToRead = n;

// запись в зашифрованный файл

CrStream. Write(bytes, 0, numBytesToRead);

// очистка памяти с конфиденциальными данными

rc2CSP. Clear();

// закрытие потока шифрования

CrStream. Close();

// закрытие файлов

finStream. Close();

foutStream. Close();

// вывод сообщения о результате шифрования файла

MessageBox. Show("Файл " + InputFName. Text +

" зашифрован в файле " + OutputFName. Text +

" с эффективной длиной ключа " +

rc2CSP. EffectiveKeySize. ToString() + " бит");

/* удаление исходного файла, если выбран соответствующий режим работы */

if (DelInputFile. Checked) File. Delete(InputFName. Text);

// очистка элементов управления от введенной информации

InputFName. Clear();

DelInputFile. Checked = false;

OutputFName. Clear();

PassFrase1.Clear();

PassFrase2.Clear();

}

// обработка ошибки криптографической операции

catch (CryptographicException ex)

{

// вывод сообщения об ошибке

MessageBox. Show(ex. Message, "Ошибка", MessageBoxButtons. OK,

MessageBoxIcon. Error);

// закрытие файлов

finStream. Close();

foutStream. Close();

}

// обработка остальных ошибок

catch (Exception ex)

{

// вывод сообщения об ошибке

MessageBox. Show(ex. Message, "Ошибка", MessageBoxButtons. OK,

MessageBoxIcon. Error);

}

}

// обработка изменения текста, введенного в редактируемых строках

private void InputFName_TextChanged(object sender, EventArgs e)

{

/* есди выбрано имя исходного файла и введена парольная фраза с подтверждением, то кнопки "Зашифровать" и "Расшифровать" доступны */

Encrypt. Enabled = (InputFName. Text. Length>0) &&

(PassFrase1.Text. Length>0) && (PassFrase2.Text. Length>0);

Decrypt. Enabled = (InputFName. Text. Length > 0) &&

(PassFrase1.Text. Length > 0) && (PassFrase2.Text. Length > 0);

}

// обработка нажатия кнопки "Расшифровать"

private void Decrypt_Click(object sender, EventArgs e)

{

try

{

// проверка совпадения парольной фразы и ее подтверждения

if (PassFrase1.Text!= PassFrase2.Text)

throw ex = new ArgumentException

("Парольная фраза и ее подтверждение не совпадают.");

/* создание объекта для исходного (зашифрованного) файлового потока */

finStream = new FileStream(InputFName. Text, FileMode. Open);

// создание буфера для случайной примеси

randBytes = new byte[8];

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

finStream. Read(randBytes, 0, 8);

// декодирование парольной фразы

byte[] pwd = Encoding. Unicode. GetBytes(PassFrase1.Text);

// создание объекта для генерации ключа из парольной фразы

pdb = new PasswordDeriveBytes(pwd, randBytes);

// сброс состояния объекта для алгоритма шифрования

rc2CSP. Clear();

/* генерация ключа (значение начального вектора выьирается по умолчанию) */

rc2CSP. Key = pdb. CryptDeriveKey("RC2", "MD5",

(int)KeyLen. Value, IV);

// создание объекта расшифрования

ICryptoTransform decryptor =

rc2CSP. CreateDecryptor(rc2CSP. Key, IV);

/* сохранение и отображение имени результирующего (расшифрованного) файла */

/* если расширение имени исходного файла равно. enc, то оно удаляется */

if (InputFName. Text. IndexOf(".enc") != -1)

OutputFName. Text = InputFName. bstring(0,

InputFName. Text. IndexOf(".enc"));

// иначе к имени исходного файла добавляется расширение. dec

else OutputFName. Text = InputFName. Text + ".dec";

/* создание объектов для результирующего файлового потока и потока расшифрования */

foutStream = new FileStream(OutputFName. Text, FileMode. Create);

CrStream = new CryptoStream(finStream, decryptor,

CryptoStreamMode. Read);

// выделение памяти для буфера ввода-вывода

bytes = new byte[finStream. Length-8];

// задание количества непрочитанных байт

numBytesToRead = (int)(finStream. Length)-8;

// ввод данных из исходного файла

int n=CrStream. Read(bytes, 0, numBytesToRead);

// сохранение фактического количества прочитанных байт

numBytesToRead = n;

// запись в расшифрованный файл

foutStream. Write(bytes, 0, numBytesToRead);

// очистка памяти с конфиденциальными данными

rc2CSP. Clear();

// закрытие потока

CrStream. Close();

// закрытие исходного файла

finStream. Close();

// закрытие результирующего файла

foutStream. Close();

// вывод сообщения о результате шифрования файла

MessageBox. Show("Файл " + InputFName. Text +

" расшифрован в файле " + OutputFName. Text);

/* удаление исходного файла, если выбран соответствующий режим работы */

if (DelInputFile. Checked) File. Delete(InputFName. Text);

// очистка элементов управления от введенной информации

InputFName. Clear();

DelInputFile. Checked = false;

OutputFName. Clear();

PassFrase1.Clear();

PassFrase2.Clear();

}

// обработка ошибки криптографической операции

catch (CryptographicException ex)

{

// вывод сообщения об ошибке

MessageBox. Show(ex. Message, "Ошибка", MessageBoxButtons. OK,

MessageBoxIcon. Error);

// закрытие файлов

finStream. Close();

foutStream. Close();

}

// обработка остальных ошибок

catch (Exception ex)

{

// вывод сообщения об ошибке

MessageBox. Show(ex. Message, "Ошибка", MessageBoxButtons. OK,

MessageBoxIcon. Error);

}

}

}

}

Во втором примере рассмотрим шифрование и расшифрование по алгоритму AES в режиме сцепления блоков шифра на случайно генерируемом секретном ключе введенного пользователем сообщения, длина которого не больше 20 символов. На рис. 2 приведено главное окно этого приложения.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15