// определение режима блочного шифрования
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 |


