|
При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Xna.Framework.Graphics;
namespace Application1 { public partial class MainForm : Form { // Объявим поле графического устройства для видимости в методах GraphicsDevice device;
public MainForm() { InitializeComponent();
// Подпишемся на событие Load формы this.Load += new EventHandler(MainForm_Load);
// Попишемся на событие FormClosed формы this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed); }
void MainForm_FormClosed(object sender, FormClosedEventArgs e) { // Удаляем (освобождаем) устройство device.Dispose(); // На всякий случай присваиваем ссылке на устройство значение null device = null; }
void MainForm_Load(object sender, EventArgs e) { // Создаем объект представления для настройки графического устройства PresentationParameters presentParams = new PresentationParameters(); // Настраиваем объект представления через его свойства presentParams.IsFullScreen = false; // Включаем оконный режим presentParams.BackBufferCount = 1; // Включаем задний буфер // для двойной буферизации // Переключение переднего и заднего буферов // должно осуществляться с максимальной эффективностью presentParams.SwapEffect = SwapEffect.Discard; // Устанавливаем размеры заднего буфера по клиентской области окна формы presentParams.BackBufferWidth = this.ClientSize.Width; presentParams.BackBufferHeight = this.ClientSize.Height;
// Создадим графическое устройство с заданными настройками device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.Handle, presentParams); }
protected override void OnPaint(PaintEventArgs e) { device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);
base.OnPaint(e); } } } Выбрасывается исключение: Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл. Делаю все пунктуально. В чем может быть проблема? |
Работа с потоками данных
Пример 3. Поток CryptoStream и электронные подписи документов
Чтобы уж совсем завершить тему потока CryptoStream, рассмотрим еще одну сферу его применения - электронные подписи документов. Иногда получатель документа должен быть уверен, что этот документ не был искажен. В этом случае отправитель и получатель договариваются об одном и том же секретном ключе и применяют специальные алгоритмы хеширования, использующие ключ.
Напомним, что любые хеш-алгоритмы всегда генерируют значение постоянной длины (каждый своей) независимо от длины хешируемого текста. Но алгоритмы хеширования с ключами HMAC ( Hash Message Authentication ) отличаются от обычных алгоритмов хеширования тем, что они генерируют хеш на основании ключа. Отправитель документа вычисляет его хеш на основании секретного ключа и отправляет вместе с ключем получателю. Получатель извлекает хеш из присланного документа и повторно хеширует сам оставшийся документ с применением своего дубликата ключа. Если вычисленный хеш совпадает с полученным, то подлинность документа считается установленной.
Библиотека .NET Framework поддерживает задачи электронных подписей несколькими классами-алгоритмами пространства имен System.Security.Cryptography. Они принимают ключи разного размера и производят хеш-значение разной длины. Если длина применяемых ключей отличается от разрешенной, то любой из алгоритмов генерирует исключение.
Построим работоспособное приложение, выполняющее электронную подпись документа и устанавливающее его подлинность. Код приведем по сокращенной программе - без объяснений (достаточно комментариев, разберетесь, кто захочет!).
-
Добавьте к решению CryptoStream новый проект с именем Demo3 и назначьте его стартовым
-
Откройте интерфейсный файл Form1.Designer.cs и заполните его следующим кодом (приводится полностью)
namespace Demo3
{
partial class Form1
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.cmbHMAC = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.txtSourceFile = new System.Windows.Forms.TextBox();
this.btnSelectFile = new System.Windows.Forms.Button();
this.txtDestinationDir = new System.Windows.Forms.TextBox();
this.btnDestinationDir = new System.Windows.Forms.Button();
this.label4 = new System.Windows.Forms.Label();
this.txtKey = new System.Windows.Forms.TextBox();
this.btnClose = new System.Windows.Forms.Button();
this.lblInfo = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.btnSigned = new System.Windows.Forms.Button();
this.btnChecked = new System.Windows.Forms.Button();
this.btnShowFile = new System.Windows.Forms.Button();
this.btnNewFile = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// cmbHMAC
//
this.cmbHMAC.FormattingEnabled = true;
this.cmbHMAC.Location = new System.Drawing.Point(94, 21);
this.cmbHMAC.Name = "cmbHMAC";
this.cmbHMAC.Size = new System.Drawing.Size(280, 24);
this.cmbHMAC.TabIndex = 0;
this.cmbHMAC.SelectedIndexChanged += new System.EventHandler(this.cmbHMAC_SelectedIndexChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(36, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(51, 17);
this.label1.TabIndex = 1;
this.label1.Text = "HMAC:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(5, 156);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(83, 17);
this.label2.TabIndex = 2;
this.label2.Text = "Source File:";
//
// txtSourceFile
//
this.txtSourceFile.Location = new System.Drawing.Point(94, 155);
this.txtSourceFile.Name = "txtSourceFile";
this.txtSourceFile.Size = new System.Drawing.Size(280, 22);
this.txtSourceFile.TabIndex = 3;
this.txtSourceFile.KeyDown += new System.Windows.Forms.KeyEventHandler(this.EditKeyDown);
this.txtSourceFile.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.EditKeyPress);
//
// btnSelectFile
//
this.btnSelectFile.Font = new System.Drawing.Font("Agency FB", 7.2F, System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnSelectFile.Location = new System.Drawing.Point(380, 155);
this.btnSelectFile.Name = "btnSelectFile";
this.btnSelectFile.Size = new System.Drawing.Size(25, 23);
this.btnSelectFile.TabIndex = 4;
this.btnSelectFile.Text = "...";
this.btnSelectFile.UseVisualStyleBackColor = true;
this.btnSelectFile.Click += new System.EventHandler(this.btnSelectFile_Click);
//
// txtDestinationDir
//
this.txtDestinationDir.Location = new System.Drawing.Point(94, 198);
this.txtDestinationDir.Name = "txtDestinationDir";
this.txtDestinationDir.Size = new System.Drawing.Size(280, 22);
this.txtDestinationDir.TabIndex = 6;
//
// btnDestinationDir
//
this.btnDestinationDir.Font = new System.Drawing.Font("Agency FB", 7.2F, System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnDestinationDir.Location = new System.Drawing.Point(380, 198);
this.btnDestinationDir.Name = "btnDestinationDir";
this.btnDestinationDir.Size = new System.Drawing.Size(25, 23);
this.btnDestinationDir.TabIndex = 7;
this.btnDestinationDir.Text = "...";
this.btnDestinationDir.UseVisualStyleBackColor = true;
this.btnDestinationDir.Click += new System.EventHandler(this.btnDestinationDir_Click);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(52, 67);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(36, 17);
this.label4.TabIndex = 8;
this.label4.Text = "Key:";
//
// txtKey
//
this.txtKey.Location = new System.Drawing.Point(94, 66);
this.txtKey.Name = "txtKey";
this.txtKey.Size = new System.Drawing.Size(280, 22);
this.txtKey.TabIndex = 9;
//
// btnClose
//
this.btnClose.AutoSize = true;
this.btnClose.Location = new System.Drawing.Point(353, 256);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(75, 27);
this.btnClose.TabIndex = 12;
this.btnClose.Text = "Close";
this.btnClose.UseVisualStyleBackColor = true;
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
//
// lblInfo
//
this.lblInfo.AutoSize = true;
this.lblInfo.Location = new System.Drawing.Point(104, 110);
this.lblInfo.Name = "lblInfo";
this.lblInfo.Size = new System.Drawing.Size(45, 17);
this.lblInfo.TabIndex = 15;
this.lblInfo.Text = "lblInfo";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(8, 186);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(79, 34);
this.label3.TabIndex = 5;
this.label3.Text = "Destination\r\ndirectory:";
this.label3.TextAlign = System.Drawing.ContentAlignment.TopRight;
//
// btnSigned
//
this.btnSigned.AutoSize = true;
this.btnSigned.Location = new System.Drawing.Point(98, 256);
this.btnSigned.Name = "btnSigned";
this.btnSigned.Size = new System.Drawing.Size(75, 27);
this.btnSigned.TabIndex = 19;
this.btnSigned.Text = "Signed";
this.btnSigned.UseVisualStyleBackColor = true;
this.btnSigned.Click += new System.EventHandler(this.btnSigned_Click);
//
// btnChecked
//
this.btnChecked.AutoSize = true;
this.btnChecked.Location = new System.Drawing.Point(182, 256);
this.btnChecked.Name = "btnChecked";
this.btnChecked.Size = new System.Drawing.Size(75, 27);
this.btnChecked.TabIndex = 20;
this.btnChecked.Text = "Checked";
this.btnChecked.UseVisualStyleBackColor = true;
this.btnChecked.Click += new System.EventHandler(this.btnChecked_Click);
//
// btnShowFile
//
this.btnShowFile.AutoSize = true;
this.btnShowFile.Location = new System.Drawing.Point(266, 256);
this.btnShowFile.Name = "btnShowFile";
this.btnShowFile.Size = new System.Drawing.Size(78, 27);
this.btnShowFile.TabIndex = 21;
this.btnShowFile.Text = "Show File";
this.btnShowFile.UseVisualStyleBackColor = true;
this.btnShowFile.Click += new System.EventHandler(this.btnShowFile_Click);
//
// btnNewFile
//
this.btnNewFile.AutoSize = true;
this.btnNewFile.Location = new System.Drawing.Point(14, 256);
this.btnNewFile.Name = "btnNewFile";
this.btnNewFile.Size = new System.Drawing.Size(75, 27);
this.btnNewFile.TabIndex = 22;
this.btnNewFile.Text = "New File";
this.btnNewFile.UseVisualStyleBackColor = true;
this.btnNewFile.Click += new System.EventHandler(this.btnNewFile_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(442, 296);
this.Controls.Add(this.btnNewFile);
this.Controls.Add(this.btnShowFile);
this.Controls.Add(this.btnChecked);
this.Controls.Add(this.btnSigned);
this.Controls.Add(this.lblInfo);
this.Controls.Add(this.btnClose);
this.Controls.Add(this.txtKey);
this.Controls.Add(this.label4);
this.Controls.Add(this.btnDestinationDir);
this.Controls.Add(this.txtDestinationDir);
this.Controls.Add(this.label3);
this.Controls.Add(this.btnSelectFile);
this.Controls.Add(this.txtSourceFile);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.cmbHMAC);
this.MaximizeBox = false;
this.Name = "Form1";
this.Text = "HMAC Algorithm with Files";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ComboBox cmbHMAC;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtSourceFile;
private System.Windows.Forms.Button btnSelectFile;
private System.Windows.Forms.TextBox txtDestinationDir;
private System.Windows.Forms.Button btnDestinationDir;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox txtKey;
private System.Windows.Forms.Button btnClose;
private System.Windows.Forms.Label lblInfo;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button btnSigned;
private System.Windows.Forms.Button btnChecked;
private System.Windows.Forms.Button btnShowFile;
private System.Windows.Forms.Button btnNewFile;
}
}-
Откройте файл Form1.cs в режиме View Code и заполните его следующим кодом (приводится полностью)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
// Дополнительные пространства имен
using System.Security.Cryptography;
using System.IO;
namespace Demo3
{
public partial class Form1 : Form
{
// Объявляем ссылку на объект для хеширования документов
KeyedHashAlgorithm hmac = null;// Тип общего предка
// Создаем объект сохранения параметров
MySettings settings = new MySettings();// Это наш класс в файле MySettings.cs
public Form1()
{
InitializeComponent();
// Привязка именованных параметров к
// сохраняемым свойствам элементов управления
txtDestinationDir.DataBindings.Add(new Binding("Text", settings, "DestinationDir"));
txtSourceFile.DataBindings.Add(new Binding("Text", settings, "SourceFile"));
// Настраиваем ComboBox динамически
cmbHMAC.Items.AddRange(
new string[]
{
"HMACSHA1",
"MACTripleDES",
"HMACMD5",
"HMACRIPEMD160",
"HMACSHA256",
"HMACSHA384",
"HMACSHA512"
});
cmbHMAC.SelectedIndex = 0;// Выделяем первый элемент
}
// Меняем алгоритм хеширования
private void cmbHMAC_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox cmb = sender as ComboBox;
switch (cmb.SelectedIndex)
{
case 0:
hmac = new HMACSHA1();
break;
case 1:
hmac = new MACTripleDES();
break;
case 2:
hmac = new HMACMD5();
break;
case 3:
hmac = new HMACRIPEMD160();
break;
case 4:
hmac = new HMACSHA256();
break;
case 5:
hmac = new HMACSHA384();
break;
case 6:
hmac = new HMACSHA512();
break;
}
CorrectTextKey();
}
// Устанавливаем допустимую длину ввода
void CorrectTextKey()
{
// Корректируем длину поля ввода ключа
int lenKey = hmac.Key.Length;
int lenTextBox = ASCIIEncoding.ASCII.GetByteCount(txtKey.Text);
if (lenTextBox > lenKey)// Убираем лишнее
txtKey.Text = txtKey.Text.Substring(0, lenKey);
txtKey.MaxLength = lenKey;// Ограничение в поле ввода
// Отображаем в текстовой метке
lblInfo.Text = String.Format("Key Size: {0} bytes Hash Size: {1} bytes",
hmac.Key.Length, hmac.HashSize / 8);
}
// Создать новый текстовый файл через блокнот
private void btnNewFile_Click(object sender, EventArgs e)
{
// Создаем новый текстовый файл через блокнот
System.Diagnostics.Process exe = new System.Diagnostics.Process();
exe.StartInfo.FileName = "Notepad.exe"; //Имя программы для запуска
//exe.StartInfo.Arguments = path; //Аргументы
exe.Start(); // Запускаем внешний процесс
//exe.WaitForExit();// Останавливаем наш процесс до закрытия блокнота
exe.Close(); // Освобождаем связанные с процессом ресурсы
}
// Посмотреть через блокнот результаты
private void btnShowFile_Click(object sender, EventArgs e)
{
// Покажем выбранный файл через блокнот
System.Diagnostics.Process exe = new System.Diagnostics.Process();
exe.StartInfo.FileName = "Notepad.exe"; //Имя программы для запуска
exe.StartInfo.Arguments = SelectFile(); //Выбрать файл через диалог
exe.Start(); // Запускаем внешний процесс
//exe.WaitForExit();// Останавливаем наш процесс до закрытия блокнота
exe.Close(); // Освобождаем связанные с процессом ресурсы
}
// Подписать документ
private void btnSigned_Click(object sender, EventArgs e)
{
if (txtKey.Text == "")
{
MessageBox.Show(this, "Введите ключ для хеширования", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
string destinationFile = "";
if (Path.GetExtension(txtSourceFile.Text) != ".txt")
{
MessageBox.Show(this, "Выберите файл '*.txt' для хеширования", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
else
{
destinationFile = txtSourceFile.Text.Replace(".txt", String.Empty) + ".sign";
destinationFile = Path.GetFileName(destinationFile);// Укороченное имя
destinationFile = Path.Combine(txtDestinationDir.Text, destinationFile);
}
if (signedData(txtSourceFile.Text, destinationFile, txtKey.Text))
MessageBox.Show(this, "Выполнено!", "Подписание файла",
MessageBoxButtons.OK, MessageBoxIcon.Information);
else
MessageBox.Show(this, "Процесс подписания закончился неудачей!", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
// Выполнить аутентификацию документа
private void btnChecked_Click(object sender, EventArgs e)
{
if (txtKey.Text == "")
{
MessageBox.Show(this, "Введите ключ для аутентификации", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
string destinationFile = "";
if (Path.GetExtension(txtSourceFile.Text) != ".sign")
{
MessageBox.Show(this, "Выберите файл '*.sign' для аутентификации", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
else
{
destinationFile = txtSourceFile.Text + ".txt";
destinationFile = Path.GetFileName(destinationFile);// Укороченное имя
destinationFile = Path.Combine(txtDestinationDir.Text, destinationFile);
}
if (checkedData(txtSourceFile.Text, destinationFile, txtKey.Text))
MessageBox.Show(this, "Выполнено!", "Аутентификация файла",
MessageBoxButtons.OK, MessageBoxIcon.Information);
else
MessageBox.Show(this, "Процесс аутентификации закончился неудачей!", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
// Подписываем заданный файл
private bool signedData(
string sourceFile, string destinationFile, string cryptoKey)
{
FileStream inFileStream = null, outFileStream = null;
// Создаем заново, иначе барахлит
switch (cmbHMAC.SelectedIndex)
{
case 0:
hmac = new HMACSHA1();
break;
case 1:
hmac = new MACTripleDES();
break;
case 2:
hmac = new HMACMD5();
break;
case 3:
hmac = new HMACRIPEMD160();
break;
case 4:
hmac = new HMACSHA256();
break;
case 5:
hmac = new HMACSHA384();
break;
case 6:
hmac = new HMACSHA512();
break;
}
try
{
// Настраиваем алгоритм хеширования
byte[] key = new byte[hmac.Key.Length];// Заготавливаем требуемый размер ключа
ASCIIEncoding.ASCII.GetBytes(cryptoKey.Trim()).CopyTo(key, 0);// Заполняем ключ
hmac.Key = key;
// Создаем оболочку CryptoStream для хеширования 'в никуда'
CryptoStream cryptoStream = new CryptoStream(Stream.Null, hmac, CryptoStreamMode.Write);
// Открываем исходный файл, используя файловый поток
inFileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read);
// Объявляем массив байтов с длиной входного файла
byte[] bytes = new byte[inFileStream.Length];
// Считываем входной файловый поток в массив байтов и записываем
// байты в CryptoStream, чтобы получить хеш исходного документа
inFileStream.Read(bytes, 0, bytes.Length);
cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.Close();
// Извлекаем хеш и записываем все в выходной документ
outFileStream = new FileStream(destinationFile, FileMode.Create, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(outFileStream);
bw.Write(hmac.Hash.Length);// Пишем длину хеша
outFileStream.Write(hmac.Hash, 0, hmac.Hash.Length);// Пишем сам хеш
inFileStream.Position = 0;// Указатель в начало
inFileStream.Read(bytes, 0, bytes.Length); // Читаем исходный файл
outFileStream.Write(bytes, 0, bytes.Length); // Пишем сам документ
return true;
}
catch (Exception e)
{
MessageBox.Show(this, e.ToString(), "Hashed Error",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
return false;
}
finally
{
// Освобождаем файловые ресурсы в любом случае
if (inFileStream != null) inFileStream.Close();
if (outFileStream != null) outFileStream.Close();
}
}
// Хешируем указанный файл с тем же ключем и алгоритмом
private bool checkedData(
string sourceFile, string destinationFile, string cryptoKey)
{
FileStream inFileStream = null, outFileStream = null;
// Создаем заново, иначе барахлит
switch (cmbHMAC.SelectedIndex)
{
case 0:
hmac = new HMACSHA1();
break;
case 1:
hmac = new MACTripleDES();
break;
case 2:
hmac = new HMACMD5();
break;
case 3:
hmac = new HMACRIPEMD160();
break;
case 4:
hmac = new HMACSHA256();
break;
case 5:
hmac = new HMACSHA384();
break;
case 6:
hmac = new HMACSHA512();
break;
}
try
{
// Настраиваем алгоритм хеширования
byte[] key = new byte[hmac.Key.Length];// Заготавливаем требуемый размер ключа
ASCIIEncoding.ASCII.GetBytes(cryptoKey.Trim()).CopyTo(key, 0);// Заполняем ключ
hmac.Key = key;
// Создаем оболочку CryptoStream для хеширования 'в никуда'
CryptoStream cryptoStream = new CryptoStream(Stream.Null, hmac, CryptoStreamMode.Write);
// Открываем исходный файл и извлекаем хеш
inFileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(inFileStream);// Вспомогательная оболочка
int hashLength = br.ReadInt32();// Читаем длину хеша
byte[] receivedHash = new byte[hashLength];// Место под хеш
inFileStream.Read(receivedHash, 0, receivedHash.Length);// Извлекаем хеш
long posBeginDoc = inFileStream.Position;// Начало документа
// Объявляем массив байтов тела документа
byte[] bytes = new byte[inFileStream.Length - posBeginDoc];
// Дочитываем документ в массив байтов и записываем байты
// в CryptoStream, чтобы получить хеш исходного документа
inFileStream.Read(bytes, 0, bytes.Length);
cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.Close();
// Извлекаем хеш и сравниваем с присланным
// Преобразование ASCIIEncoding.ASCII.GetString() сбоит!
String strCurrentHash = Encoding.Unicode.GetString(hmac.Hash);// byte[] -> string
String strReceivedHash = Encoding.Unicode.GetString(receivedHash);// Присланный хеш
if (strCurrentHash.CompareTo(strReceivedHash) != 0)
MessageBox.Show("Документ фальсифицирован!");
else
{
inFileStream.Position = posBeginDoc;
inFileStream.Read(bytes, 0, bytes.Length);
outFileStream = new FileStream(destinationFile, FileMode.Create, FileAccess.Write);
outFileStream.Write(bytes, 0, bytes.Length);
outFileStream.Flush();
MessageBox.Show("Документ подлинный и очищен от хеша!");
}
return true;
}
catch (Exception e)
{
MessageBox.Show(this, e.ToString(), "Checked Error",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
return false;
}
finally
{
// Освобождаем файловые ресурсы в любом случае
if (inFileStream != null) inFileStream.Close();
if (outFileStream != null) outFileStream.Close();
}
}
// Диалог выбора файла для обработки
OpenFileDialog openFileDialog = new OpenFileDialog();
String SelectFile()
{
// Настраиваем диалог выбора файла
if (txtSourceFile.Text == String.Empty)
openFileDialog.InitialDirectory = txtDestinationDir.Text;
else
openFileDialog.InitialDirectory = Path.GetDirectoryName(txtSourceFile.Text);
openFileDialog.FileName = "";
openFileDialog.Filter = "Source Files(*.txt;*.sign)|*.txt;*.sign";
DialogResult result = openFileDialog.ShowDialog();
if (result != DialogResult.Cancel)
return openFileDialog.FileName; // Полное имя
else
return txtSourceFile.Text;
}
// Запуск диалога выбора файла
private void btnSelectFile_Click(object sender, EventArgs e)
{
txtSourceFile.Text = SelectFile();
txtSourceFile.Focus();// Без этого не сохранится в установках приложения
}
// Запуск диалога выбора папки назначения
FolderBrowserDialog dialogFolder = new FolderBrowserDialog();
private void btnDestinationDir_Click(object sender, EventArgs e)
{
if (txtDestinationDir.Text == String.Empty ||
Directory.Exists(txtDestinationDir.Text) == false)
{
dialogFolder.RootFolder =
System.Environment.SpecialFolder.MyComputer;
dialogFolder.SelectedPath = "";
txtDestinationDir.Text = String.Empty;
}
else
{
dialogFolder.SelectedPath = txtDestinationDir.Text;
}
dialogFolder.Description =
"Выберите место размещения целевого файла";
dialogFolder.ShowDialog();
txtDestinationDir.Text = dialogFolder.SelectedPath;
txtDestinationDir.Focus();
}
// Блокировка редактирования TextBox вручную
private void EditKeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
}
private void EditKeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
}
// При закрытии формы сохраняем параметры
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
settings.Save();
}
// Закрываем форму
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
}
}Здесь мы применили двоичные потоки BinaryReader и BinaryWriter вместо текстовых StreamReader и StreamWriter, поскольку последние оставляют в документе невидимые метки и меняют хеш (пачкают). Кодировщики Unicode тоже точнее преобразуют хеш, который может содержать отличные от ASCII символы.
-
Добавьте к текущему проекту командой Project/Add Class новый файл с именем MySettings.cs и заполните его следующим кодом (приводится полностью)
using System;
using System.Configuration;
namespace Demo3
{
// Класс для сохранения параметров приложения
class MySettings : ApplicationSettingsBase
{
[UserScopedSettingAttribute()] // Область действия - 'Пользователь'
[DefaultSettingValueAttribute("C:\\")] // Значение параметра по умолчанию
public String DestinationDir
{
get
{
return ((String)this["DestinationDir"]);
}
set
{
this["DestinationDir"] = (String)value;
}
}
[UserScopedSettingAttribute()] // Область действия - 'Пользователь'
[DefaultSettingValueAttribute("")] // Значение параметра по умолчанию
public String SourceFile
{
get
{
return ((String)this["SourceFile"]);
}
set
{
this["SourceFile"] = (String)value;
}
}
}
}-
Запустите приложение Demo3 - оно вполне работоспособно, подписывает документы и проводит их аутентификацию -
Разберитесь с кодом ( кому надо!), да пусть еще больше простят меня классики
Внешний вид окна будет таким
Естественно, что при прямой и обратной обработке одного и того же документа алгоритм и ключ должны быть одинаковыми.
Дальше пока сами... (опять по шпалам!)


