При выполнении в лабораторной работе упражнения №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 - оно вполне работоспособно, подписывает документы и проводит их аутентификацию
- Разберитесь с кодом ( кому надо!), да пусть еще больше простят меня классики
Внешний вид окна будет таким
Естественно, что при прямой и обратной обработке одного и того же документа алгоритм и ключ должны быть одинаковыми.
Дальше пока сами... (опять по шпалам!)