Частина 3 – Криптографія

У попередніх двох частинах статті були розглянуті питання
аутентифікації та авторизації користувачів. Нагадаємо, що аутентифікація
має на увазі під собою введення імені логіна і його пароля, тобто
реєстрацію; а авторизація – це перевірка прав доступу до певного
ресурсу або на виконання будь-яких дій. Нерозкритим залишився
останнє питання – криптографія.

Основне завдання криптографії – зробити кінцеві дані незрозумілими
для третіх осіб. Перші і прості методи шифрування почали
зустрічатися ще в епоху античності: існував так званий метод
Цезаря, який полягав у зміщенні кожного символу тексту на три
позиції вперед за алфавітом. Але якщо дві з гаком тисячі років тому
криптографія мала лише практичне уявлення, то сьогодні
існує ціла наука кріптологія, що займається питаннями шифрування і
дешифрування і має міцну теоретичну базу.

Класифікація

У зв'язку з великою кількістю криптометоди групувати їх можна за різними
ознаками, тому існує декілька видів класифікації. Ми
зупинимося лише на двох з них: перший заснований на області застосування,
а другий – на принципі дії.

Класифікація на основі області застосування поділяє всі
криптосистеми на дві групи: на системи обмеженого використання
і на системи загального використання. До першої групи належать
криптометоди, стійкість яких визначається тим, наскільки довго
алгоритм шифрування / дешифрування буде знаходитися в секреті. Найчастіше
прикладами таких криптосистем є системи, які не використовують паролі.
До другої групи, відповідно, належать криптометоди, стійкість
яких не залежить від алгоритму, тобто, частіше за все, їх надійність
впирається в ключ.

Криптографія, крім приховування інформації від "чужих очей і вух", також
дозволяє переконатися в достовірності отриманих даних, тобто визначити,
чи були вони спотворені при передачі; а також дозволяє визначити
відправника, іншими словами, дає деяку гарантію, що дані отримані
від легального відправника. На основі такої широкої області застосування
криптометоди з'явився ще один тип класифікації – класифікація за
принципом дії.

Під терміном
"Спотворення даних при передачі"Розуміється навмисний перехоплення і
зміна інформації при її трансляції по мережах.

Офіційно члени, класифіковані за принципом дії, прийнято
назвати криптографічними примітивами (Cryptographic Primitives).
Існують наступні примітиви:

 

Криптографічний примітив Опис
Шифрування з секретним ключем
(Симетрична система)
Представляє дані в недоступному
для третіх осіб вигляді, використовуючи єдиний секретний ключ для
шифрування і дешифрування.
Шифрування з відкритим ключем
(Асиметрична система)
Представляє дані в недоступному
для третіх осіб вигляді, використовуючи пару з відкритого та секретного
ключів для шифрування і дешифрування.
Криптографічний підпис Дозволяє упевнитися, що
дані отримані від відповідного відправника шляхом створення
цифрового підпису, властивої лише даному відправнику.
Використовує хеш-функції
Криптографічне хешування Перетворює дані будь-якої довжини в
поєднання байтів фіксованої довжини. Хеші найчастіше унікальні,
тому поєднання з двох різних байт не хешіруются в один і
той самий результат. Застосовується при верифікації даних.

Розглянемо ці примітиви детальніше.

Шифрування з секретним ключем

Криптометоди з секретним ключем, або як їх ще називають
симетричні методи
, Використовують один і той же ключ для шифрування і
дешифрування, тому його потрібно зберігати в секреті від третіх осіб,
оскільки, знаючи ключ і маючи відповідний криптоалгоритм,
зловмисник може дешифрувати дані. Симетричні системи відрізняються
високою швидкістю роботи (у порівнянні з асиметричними), що дозволяє
застосовувати їх для шифрування великого об'єму даних.

Симетричні криптосистеми діляться в свою чергу ще на дві групи:
на блокові і потокові методи.

Блокові шифри застосовують один і той же перетворення до тексту,
розбитому на блоки, довжина яких може бути дорівнює 8, 16, 24, 32 байтам
в залежності від криптометоди. Криптосистема, що надається. NET
працює за принципом побудови ланцюжка блокових шифрів (Cipher Block
Chaining – CBC), яка використовує ключ і вектор ініціалізації
(Initialization Vector – IV). Проста блочна система шифрування,
Невикор вектора ініціалізації, перетворює один і той же блок
вихідного тексту в той же самий блок зашифрованого тексту, тобто без
всяких переміщень і рекомбінації. Якщо у вас був дубльований блок у
вихідному тексті, то він з'явиться і зашифрованому. У результаті, знаючи
структуру вихідного тексту, зловмисник може дешифрувати
відповідну частину криптограми та визначити ключ шифрування. Щоб
цього уникнути, в технології CBC інформація з попереднього блоку
впроваджується в шіфруемий наступний блок. Оскільки такий підхід використовує
попередній блок для шифрування наступного, то IV шифрує найперший
блок. Це дозволяє захистити заголовок (перший блок), щоб зломщик не
міг використовувати його для отримання ключа.

Необхідність
використання IV для шифрування 1-го блоку виникає через те, що
застосування попереднього блоку для шифрування наступного починається лише
з 2-го блоку, оскільки в 1-го немає попереднього блоку – він і так стоїть в
самому початку.

Інша група симетричних криптосистем – потокові методи. Ці методи
застосовують змінюються під час шифрування перетворення до наборів
символів, які утворюють єдиний вихідний текст.

Серед симетричних алгоритмів можна виділити наступні: DES (Data
Encryption Standard), DES 2, різні варіації TripleDES, Rijndael / AES
(Advanced Encryption Standard), RC2, RC4, ГОСТ 28147-89 … Якщо поглянути
на їх алгоритми, то очевидно, що багато з них засновані на операторі
XOr. Взагалі, вперше оператор "виключає або"Був застосований в
так званому методі одноразових блокнотів, Вивчений Клодом
Шенноном. Діяв цей метод за наступним принципом: бралася рядок
вихідного тексту і рядок ключа такої ж довжини, після чого кожен символ
вихідного тексту XOr'ілся з відповідним символом рядка ключа. Цей
метод працює і як шіфровщікі, і як дешифрувальник, оскільки повторний
виклик функції XOr повертає вихідне значення.

Алгоритм
TripleDES має різні конфігурації, трохи відрізняються за принципом
роботи:
*** DES-EEE3 – потрійне шифрування з різними ключами
*** DES-EDE3 – шифрує, дешифрує і ще раз шифрує з різними ключами

*** DES-EEE2 – потрійне шифрування, але однакові ключі тільки при першій
і третьої ітераціях
*** DES-EDE2 – шифрування, дешифрування і ще раз шифрування з
однаковими ключами при першій і третій ітераціях

Інфраструктура. NET Framework містить класи для роботи з
наступними методами: DES, TripleDES, RC2, Rijndael. Але якщо
скористатися послугами CryptoAPI, то можна також отримати можливість
працювати з потоковим симетричним методом шифрування RC4. Пізніше ми
розглянемо приклади використання всіх цих методів, а зараз перейдемо до
наступного криптографічному примітиву – до шифрування з відкритим ключем
(Асиметрична система).

Шифрування з відкритим ключем

При використанні асиметричного методу шифрування генеруються 2
ключа: один з них вважається секретним, а інший відкритим. Обидва ці ключа
математично взаємопов'язані, а те, який з них буде секретним, а який
відкритим визначається користувачем. При цьому немає ніякої різниці між
тим, кому з них дістанеться та чи інша роль. Відмінності з'являються на
практиці, і виражені вони повною протилежністю дій, іншими
словами, текст, зашифрований відкритим ключем, може бути розшифрований
тільки секретним, і навпаки: зашифрувавши секретним ключем, розшифрувати
вдасться тільки відкритим.

Асиметричне шифрування використовують за наступним алгоритмом.
Припустимо, у нас є актор А і актор Б. Актор А хоче
зашифрувати дані і відправити їх актору Б. Для цього актор Б повинен
спершу створити пару ключів, з якої відкритий ключ він може вільно
переслати актору А. При цьому немає явної загрози в тому, якщо хто-небудь
перехопить цей відкритий ключ під час його передачі, оскільки
повідомлення, зашифроване одним ключем, може бути дешифровано тільки
іншим.

В UML
під терміном актор розуміється якесь дійова особа

Тут і полягає основна особливість криптометоди з відкритим
ключем: якщо ви збираєтеся від кого-то отримувати дані, шифровані
асиметричним методом, або хочете, щоб хто-небудь відправив вам
інформацію, зашифровану подібною системою, то саме ви повинні
створювати пару ключів, з якої відкритий ключ потрібно відправити
кінцевому відправнику. Доводиться дотримуватися такої стратегії,
оскільки, як вже було раніше сказано, пара ключів зв'язана між собою
математично, і тому повинна бути створена на одній машині.

Отримавши від актора Б відкритий ключ, актор А шифрує повідомлення з його
допомогою, після чого відправляє вже готову криптограму актору Б.
Нарешті, актор Б успішно отримує криптотекст і дешифрує його своїм,
нікому не відомим, секретним ключем.

Частина 3   Криптографія asp net  0701201112000011749 min vs

Рис. 1 – Принцип роботи асиметричної системи

Асиметричні криптометоди дуже повільні в порівнянні з
симетричними, тому вони можуть бути застосовані для невеликих обсягів інформації.
Таке обмеження також викликано тим, що асиметричні алгоритми мають
буфер фіксованої довжини. Найчастіше асиметричні алгоритми застосовуються
для шифрування ключів від симетричних систем, оскільки відкритий ключ
асиметричного криптометоди можна спокійно відправляти в плавання по
мереж, чого не скажеш про ключі симетричних методів.

Для
порівняння: програма, що реалізує шифрування симетричним криптометоди
DES, буде працювати приблизно в 100 разів швидше, ніж програма з
асиметричним RSA. А при апаратній реалізації цих алгоритмів
співвідношення складе 1000-10000 разів.

Системи з відкритим ключем підтримують набагато більше комбінацій
ключа, що робить їх, з певної точки зору, більш безпечними. Крім
того, асиметричні алгоритми використовуються в цифрових підписах, тільки з
трохи іншим алгоритмом, але про це пізніше.

Серед алгоритмів з відкритим ключем можна виділити наступні: RSA
(Rivest-Shamir-Adleman), DSA (Digital Signature Standard), DH
(Diffie-Hellman). З цього невеликого списку. NET підтримує лише
перші два – RSA та DSA.

Цифровий підпис

Цифровий підпис служить для того, щоб можна було впевнитися,
що дані отримані від відповідної особи. Для цього застосовуються
методи хешування та шифрування з відкритим ключем. Щоб картина
відбувається виглядала ясніше, давайте повернемося до наших акторам і дамо
їм можливість, продемонструвати весь процес.

Нехай актор А вирішив відправити лист актору Б, і щоб актор Б не
сумнівався в достовірності джерела, актор А залишив у листі цифрову
підпис. Для цього актор А спершу хешіровал всі повідомлення, в результаті
чого вийшло компактна і унікальна трансформація даних. Далі
актор А використовує асиметричний криптометоди для генерації пари ключів і
відправляє відкритий ключ актору Б. Після цього, хеш шифрується
асиметричним методом, але порядок шифрування зворотний. Дані шифрується не
володар відкритого ключа, тобто актор Б, а володар секретного ключа
– Актор А. Як тільки хеш був зашифрований, вийшла готова цифрова
підпис, який актор А відправляє актору Б разом з оригінальним
повідомленням. Актор Б отримує лист і виконує зворотні дії: він
дешифрує підпис отриманим від актора А відкритим ключем, хешірует
дані відповідним хеш-методом і звіряє результат з оригінальним
повідомленням. Якщо вони ідентичні, значить можна вважати, що повідомлення
дійсно прийшло від актора А.

Пам'ятайте,
цифровий підпис не захищає дані від несанкціонованого доступу –
вона лише дає змогу зайвий раз переконатися або ж утриматися в
достовірності відправника. Для забезпечення безпеки трансльованих
даних їх потрібно шифрувати.

У платформі. NET Framework для створення та перевірки цифрового підпису
існує кілька класів. Про них ми поговоримо трохи пізніше.

Хешування

Хеш-функції служать для перетворення бінарних значень різної
довжини до бінарних значень фіксованої довжини. Всі хеши унікальні і
дуже компактні. Достатньо змінити хоча б один байт або символ у
вихідному тексті, і його хеш прийме зовсім інший вигляд.

За допомогою хешей можна дізнатися чи були змінені дані, тому що хеши двох
абсолютно однакових наборів даних також ідентичні. Давайте подивимося
на приклад.

Нехай актор А вирішив відправити актору Б повідомлення, перед цим зробивши
його хеш і зберігши результат у себе. Актор Б отримує повідомлення і, щоб
перевірити його достовірність теж створює хеш (тим же самим хеш методом)
з отриманого повідомлення і відправляє його актору А для порівняння. Якщо
хеши акторів А і Б будуть однаковими, значить дані не були
модифіковані, в іншому випадку, є всі підстави вважати, що
повідомлення відповідь було перехоплено і змінено.

Сьогодні існують різні хеш-методи, і ось список найбільш
відомих з них: MD2 (Message Digest), MD4, MD5, SHA1, SHA256, SHA384,
SHA512, HMAC. Більшість з перерахованих алгоритмів реалізовано в
інфраструктурі. NET Framework.

Криптографія засобами. NET

У більшості випадків застосування криптографічних інструментів у
середовищі. NET Framework зводиться до звернення до простору імен
System.Security.Cryptography
, Оскільки саме в ньому містяться всі
основні класи та інтерфейси для виконання кріптооперацій.

Більшість підтримуваних криптометоди використовують CryptoAPI, але все
ж є деякі новинки. Серед них: Rijndael / AES, SHA256, SHA384,
SHA512.

Криптометоди
AES (Advanced Encryption Standard) – є не що інше, як розширений
DES, що власне і випливає з його назви. Цей метод був прийнятий у
США замість DES.

Коли ми хочемо щось зашифрувати, то виключно з інтуїтивною
точки зору ми хочемо працювати з рядком, але більшість криптометоди
не працює з рядками – вони оперують масивами байтів і потоками. Для
тих, хто вперше береться за криптографію, такий підхід може здатися
трохи незвичним, але, не дивлячись на це, у вас в будь-якому випадку
залишиться тільки 4 виходи:

  1. Змиритися і використовувати масиви байтів з потоками
  2. Знайти задовольняє ваші запити альтернативу
  3. Придумати свій криптометоди
  4. Відмовитися від криптографії

Симетричні системи

 

Найпростіше шифрування за допомогою методу DES

Щоб не ходити коло та навколо, давайте створимо Web-додаток,
виконує шифрування методом DES. Для цього створіть новий проект типу
Web Application і додайте в нього наступний код:

- Лістинг 1.1 – CryptoTest / default.aspx

<% @ Page Language = "vb" AutoEventWireup = "false" Codebehind = "default.aspx.vb" Inherits = "AdvCrypter.WebForm1"%> <html>
  <head>
    <title>CryptoTest</title>
  </head>
  <body MS_POSITIONING="GridLayout">

<form id="Form1" method="post" runat="server">
		<b>Clear Text:</b><br>
<textarea id="txt" runat=server> </ textarea>
<asp:Button ID="btnEncrypt" Text="Encrypt" Runat=server/> <br> <br>
		
		<b>Encrypted Text:</b><br>
		<table><tr><td bgcolor=LightGrey>
			<asp:Label ID="lblResult" Runat=server/>
		</td></tr></table>
    </form>

  </body>
</html>

- Лістинг 1.2 – CryptoTest / default.aspx.vb

Imports System.Security.Cryptography
Imports System.Text
Imports System.IO

Public Class WebForm1
    Inherits System.Web.UI.Page

Protected WithEvents txt As System.Web.UI.HtmlControls.HtmlTextArea
Protected WithEvents btnEncrypt As System.Web.UI.WebControls.Button
Protected WithEvents lblResult As System.Web.UI.WebControls.Label

#Region " Web Form Designer Generated Code "

    ´This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent ()

    End Sub

'NOTE: The following placeholder declaration is required by the Web Form Designer.
    ´Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
        ´Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

Private Sub btnEncrypt_Click (ByVal sender As Object, ByVal e As System.EventArgs) Handles btnEncrypt.Click
'Провайдер DES-шифрування
        Dim DES As New DESCryptoServiceProvider
'Інтерфейс-шифратор
Dim DES_Encryptor As ICryptoTransform = DES.CreateEncryptor
'Файловий потік
Dim fs As New FileStream (Server.MapPath ("temp.dat"), FileMode.Create)
'Потік шифрування
        Dim DESCryptoStream As New CryptoStream(fs, _
             DES_Encryptor, CryptoStreamMode.Write)
'Клас для отримання масиву байтів з рядка і масив байтів
        Dim enc As New UnicodeEncoding, bytes() As Byte

'=========== ЕТАП 1: шифруємо дані і зберігаємо їх у файлі ============
'Отримуємо масив байтів з рядка поля txt
        bytes = enc.GetBytes(txt.Value)
'Шифруємо дані
        DESCryptoStream.Write(bytes, 0, bytes.Length)
'Закриваємо потоки
        DESCryptoStream.Close()
        fs.Close()
        fs = Nothing

'=========== ЕТАП 2: Читаємо дані із збереженого файлу =============
'Відкриваємо потік
fs = New FileStream (Server.MapPath ("temp.dat"), FileMode.Open)
'Ініціалізіруем клас-читач потоку
        Dim sr As New StreamReader(fs)
'Читаємо зашифрований текст з файлового потоку
        lblResult.Text = sr.ReadToEnd
'Закриваємо потоки
        sr.Close()
        fs.Close()

'=========== ЕТАП 3: Видаляємо тимчасовий файл 'temp.dat'===============
        File.Delete(Server.MapPath("temp.dat"))
    End Sub
End Class

У лістингу 1.2 всі основні дії відбуваються в обробнику події
натискання кнопки btnEncrypt. Давайте розглянемо його докладніше.
Спочатку створюється екземпляр провайдера шифрування. Для кожного
криптометоди існує свій провайдер, тому їхні імена оголошені
приблизно в таких форматах: <ІмяКріптометода> CryptoServiceProvider
або <ІмяКріптометода> Managed. Наприклад, DESCryptoServiceProvider,
RSACryptoServiceProvider, RijndealManaged та ін Після ініціалізації
криптопровайдера створюється змінна, що реалізує інтерфейс-шифратор;
далі відкривається файловий потік для запису даних у файл. Після цього,
ініціалізується кріптопоток, в аргументах якого задається кінцевий
потік даних (у нашому випадку – це файловий потік fs); Спосіб
криптографічного трансформації, тобто интрефейс-шифратор, і дія,
яке необхідно виконати з даними. З можливих дій виділяються
читання і запис.

В якості
кінцевого потоку даних (перший атрибут конструктора класу
CryptoStream
) Найчастіше виступає файловий потік, але це зовсім не
означає, що ви не можете використовувати інші типи потоків. Наприклад,
ASP.NET програми дозволяють використовувати потік Response.OutputStream
для виведення інформації.

На цьому зведення підготовчої майданчики для подальших
кріптооперацій закінчується. У наступних рядках коду створюється масив
байтів, оскільки, як вже було сказано, всі криптометоди середовища. NET
Framework працюють не з рядками, а з масивами байтів. Нарешті,
відбувається шифрування в наступному рядку:

DESCryptoStream.Write(bytes, 0, bytes.Length)

У цьому відрізку коду проиходит ті ж дії, що і при звичайних
операціях з потоками: методу Write передається масив байтів,
вказується зміщення і довжина цього масиву. Таким чином, весь процес
шифрування у нас вмістився всього в один рядок коду, але перед цим
довелося вибудувати масивний підготовчий плацдарм!

В кінці всі потоки закриваються, потім відкриваються знову, але вже для
читання з попередньо створеного файлу (temp.dat), Далі
файловий потік знову закривається, а тимчасовий файл видаляється.

Під час виконання програми ви можете зіткнутися з фокусом, як
на рис. 3. Це повідомлення говорить про те, що доступ заборонений для створення
файлу temp.dat. Таке відбувається в тому випадку, якщо користувача
ASPNET немає в списку ACL до папки Web-додатки.

За замовчуванням
процес ASP.NET-додатків запускається від імені користувача ASPNET,
в чому ви можете переконатися, відкривши TaskMan на вкладці Процеси
(Рис. 4)

Частина 3   Криптографія asp net  0701201112000017665 min vs

Рис. 2 – Система не дозволяє створити файл на сервері: доступ
заборонений

Частина 3   Криптографія asp net  0701201112000017666 min vs

Рис. 3 – За замовчуванням процес aspnet_wp.exe запускається від
імені користувача ASPNET

Щоб виправити становище, можна:

  1. У explorer.exe відкрити властивості папки Web-додатки
    (Адреса програми може бути наступним:
    C: Inetpubwwwroot <ІмяПрімложенія>
    ), Перейти у вкладку
    Безпека
    і додати користувача ASPNET до списку допустимих
    суб'єктів.
  2. Застосувати запозичення повноважень для Web-додатки. У цьому
    випадку можна або строго прописати необхідного користувача для
    запозичення його прав, або запозичувати права від користувача,
    запустив процес Web-додатки. Для цього достатньо змінити
    файл Web.config наступним чином:

    <? Xml version = "1.0" encoding = "utf-8"?>
    <configuration>
      <system.web>
    
        <authentication mode="Windows" /> 
    
        <authorization>
            <allow users="*" />
        </authorization>
        <identity impersonate="true"/>
    
      </system.web>
    </configuration>
    

Все, що потрібно було зробити – це додати рядок
<identity impersonate="true"/>

Інформацію про
запозиченні повноважень можна знайти у 2-ї частини цієї статті, яка
була присвячена авторизації.

Тепер, якщо додаток працює без помилок, можна попрацювати з
шифруванням. Для цього потрібно ввести який-небудь текст у полі Clear
Text
і натиснути на кнопку Encrypt. Результат повинен бути
подібний рисунком 5.

Зауважте, що
повторне шифрування однієї і тієї ж рядки повертає різні дані.

Частина 3   Криптографія asp net  0701201112000017667 min vs

Рис. 4 – Результат успішного виконання програми

Додаємо ініціалізаційний вектор (IV) і ключ

Попередній приклад був найпростішим: ми тільки зашифрували текст
без передачі будь-яких додаткових параметрів. Але згадаємо теорію: в
ній було сказано, що для ефективного захисту на симетричні
криптометоди потрібно накладати ключ і ініціалізаційний вектор (далі
IV). Цим ми зараз і займемося, а також, щоб не повторюватися, відмовимося
від файлового потоку на користь потоку виводу Response.OutputStream.

Створіть новий проект типу WebApplication і використовуйте листинги 2.1
та 2.2:

- Лістинг 2.1: AdvCrypter / default.aspx

<% @ Page Language = "vb" AutoEventWireup = "false" Codebehind = "default.aspx.vb" Inherits = "AdvCrypter.WebForm1"%> <html>
  <head>
    <title>AdvCrypter</title>
  </head>
  <body MS_POSITIONING="GridLayout">

<form id="Form1" method="post" runat="server">
		<b>Clear Text:</b><br>
<textarea id="txt" runat=server> </ textarea>
<asp:Button ID="btnEncrypt" Runat=server Text="Encrypt"/>
    </form>

  </body>
</html>

Зверніть увагу, що кількість елементів зменшилася, тому що для
відображення результату ми використовуємо потік виведення об'єкта Response.

- Лістинг 2.2: AdvCrypter / default.aspx.vb

Imports System.Security.Cryptography
Imports System.Text

Public Class WebForm1
    Inherits System.Web.UI.Page

Protected WithEvents btnEncrypt As System.Web.UI.WebControls.Button
Protected WithEvents txt As System.Web.UI.HtmlControls.HtmlTextArea

#Region " Web Form Designer Generated Code "

    ´This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent ()

    End Sub

'NOTE: The following placeholder declaration is required by the Web Form Designer.
    ´Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
        ´Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

Private Sub btnEncrypt_Click (ByVal sender As Object, ByVal e As System.EventArgs) Handles btnEncrypt.Click
'Провайдер DES-шифрування
        Dim DES As New DESCryptoServiceProvider
'Генеруємо ключ
        DES.GenerateKey()
'Генеруємо IV
        DES.GenerateIV()

'Інтерфейс-шифратор, для створення якого передаються ключ і IV
Dim DES_Encryptor As ICryptoTransform = DES.CreateEncryptor (DES.Key, DES.IV)
'Потік шифрування
Dim DESCryptoStream As New CryptoStream (Response.OutputStream, _
             DES_Encryptor, CryptoStreamMode.Write)
'Клас для отримання масиву байтів з рядка і масив байтів
        Dim enc As New UnicodeEncoding, bytes() As Byte


'Отримуємо масив байтів з рядка поля txt
        bytes = enc.GetBytes(txt.Value)
'Шифруємо дані
        DESCryptoStream.Write(bytes, 0, bytes.Length)
'Закриваємо потоки
        DESCryptoStream.Close()
    End Sub
End Class

Очевидно, що, якщо не використовувати файлові потоки, то код
виходить набагато коротше, тому що немає необхідності спочатку
відкривати потік для запису, закривати його, потім знову відкривати для
читання, отримувати з нього дані і знову закривати потік. Одним словом,
без файлів життя стає легше!

У коді також з'явилися 2 нові рядки, в яких через провайдер
алгоритму DES йде генерація ключа і IV. Потім для створення інтерфейсу
трансформації використовується інший прототип перевантаженої функції
DES.CreateEncryptor
, В якому в якості аргументів передаються ключ
і IV.


GenerateKey
і GenerateIV – Це (з точки зору VB.NET) не
функції, а процедури, тобто вони не повертають значення, а задають
властивості Key і IV в об'єкті SymmetricAlgorithm.
Саме тому в лістингу 2.2 спочатку викликаються функції генерації, а
потім значення беруться з властивостей Key і IV.

Запустивши додаток на виконання, ви як користувач ніяких
істотних змін в шифруванні не помітите, але як розробник ви
будете знати, що принцип шифрування докорінно змінився.

Якщо в
криптометоди застосовуються ключ і IV, то їх слід зберегти і при тому в
секреті від сторонніх осіб, оскільки ці дані будуть використані при
дешифрування.

Комбінування криптометоди

У попередніх прикладах ми працювали лише з методом DES, але крім нього
існує також ряд інших методів. У цьому розділі буде розглянуто
процес створення Windows-додаток, що реалізує одночасно всі
симетричні алгоритми, які підтримуються платформою. NET. Плюс до
цього, ми додамо дешифрування, але натомість відключимо підтримку ключів і
IV, оскільки інакше їх доведеться запам'ятовувати для кожного файлу в
окремо, а зберігати їх у відкритому вигляді на диску ненадійно.

Завдяки
того, що всі симетричні алгоритми в середовищі. NET Framework відбуваються
від класу SymmetricAlgorithm, Їх одночасна підтримка
значно спрощується.

Давайте тепер все розглянемо на конкретному прикладі. Для цього
створіть новий додаток Windows і створіть форму на подобу рис. 5
(Щоб не витрачати час на створення форми, можна скористатися кодом
з конструктора лістингу 3.1).

Частина 3   Криптографія asp net  0701201112000017668 min vs

Рис. 5 – Приблизний вигляд форми комбінованого
шифрування / дешифрування

- Лістинг 3.1: Приклад комбінованого шифрування і дешифрування

Imports System.IO
Imports System.Security.Cryptography
Imports System.Text

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
	´ Ця частина коду доступна на CD
#End Region

'Ключ і IV для DES і RC2
    Dim IV() As Byte = {172, 44, 172, 193, 7, 48, 131, 165}
    Dim Key() As Byte = {93, 252, 76, 113, 209, 29, 253, 168}
'Ключ і IV для TripleDES
Dim TripleKey () As Byte = {77, 79, 156, 172, 12, 40, 96, 226, _
93, 78, 90, 103, 186, 78, 117, 0, 85, 127, 114, 91, 148, 210, 242, 255}
Dim TripleIV () As Byte = {19, 127, 43, 85, 21, 117, 80, 151}
'Ключ і IV для AES
Dim aesKey () As Byte = {120, 6, 86, 102, 66, 236, 129, 91, 164, _
164, 192, 68, 70, 34, 40, 254, 107, 174, 201, 46, 168, 19, 125, _
        202, 188, 52, 75, 23, 108, 94, 114, 27}
Dim aesIV () As Byte = {196, 161, 224, 67, 23, 143, 39, 43, 188, 91, _
        247, 125, 97, 95, 246, 26}

Private Sub tlb_ButtonClick (ByVal sender As System.Object, ByVal e As 
System.Windows.Forms.ToolBarButtonClickEventArgs) Handles tlb.ButtonClick
        Dim fs As FileStream
        Dim sr As StreamReader, sw As StreamWriter

        Select Case tlb.Buttons.IndexOf(e.Button)
            Case 1          ´ New
                Text = ""
                txt1.Text = ""
                txt2.Text = ""
            Case 2          ´ Open
                If dlgO.ShowDialog = DialogResult.OK Then
fs = New FileStream (dlgO.FileName, FileMode.Open)
                    sr = New StreamReader(fs, Encoding.Default)

'Читаємо дані
                    txt1.Text = sr.ReadToEnd
                    txt2.Text = ""
                    Text = dlgO.FileName
'Закриваємо потоки
                    sr.Close()
                    fs.Close()
                End If
            Case 3          ´ Save
                If dlgS.ShowDialog = DialogResult.OK Then
fs = New FileStream (dlgS.FileName, FileMode.Create)
                    sw = New StreamWriter(fs)

'Пишемо дані
                    sw.Write(txt2.Text)
                    Text = dlgS.FileName
'Закриваємо потоки
                    sw.Close()
                    fs.Close()
                End If
        End Select
    End Sub

"Процедура шифрування
Private Sub cmdEncrypt_Click (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEncrypt.Click
Dim Alg As SymmetricAlgorithm = DefineAlg () 'Визначаємо алгоритм
        Dim Cryptor As ICryptoTransform = CreateEnc(Alg)
        Dim fs As New FileStream(GetFileName, FileMode.Create)
Dim CrStream As New CryptoStream (fs, Cryptor, CryptoStreamMode.Write)

'Отримуємо масив байтів
        Dim b() As Byte = ToBytes(txt1.Text)
'Шифруємо
        CrStream.Write(b, 0, b.Length)
'Закриваємо потік
        CrStream.Close()
        fs.Close()
        fs = Nothing


'Створюємо читач потоку
        fs = New FileStream(GetFileName, FileMode.Open)
        Dim sr As New StreamReader(fs, Encoding.Default)
'Показуємо результат
        txt2.Text = sr.ReadToEnd
'Закриваємо потоки
        sr.Close()
        fs.Close()
    End Sub

"Процедура дешифрування
Private Sub cmdDecrypt_Click (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDecrypt.Click
Dim Alg As SymmetricAlgorithm = DefineAlg () 'Визначити алгоритм
        Dim Cryptor As ICryptoTransform = CreateDec(Alg) 
        Dim fs As New FileStream(GetFileName, FileMode.Open)
Dim CrStream As New CryptoStream (fs, Cryptor, CryptoStreamMode.Read)
        Dim sr As New BinaryReader(CrStream)
'Служить для визначення розміру файлу
        Dim f As New FileInfo(GetFileName)
        Dim enc As New UnicodeEncoding

'Показуємо результат
        txt2.Text = enc.GetString(sr.ReadBytes(f.Length))
'Закриваємо потоки
        sr.Close()
        fs.Close()
    End Sub

#Region "Service functions"
'Функція, що повертає вибраний алгоритм
    Private Function DefineAlg() As SymmetricAlgorithm
        If optDES.Checked = True Then
            Return New DESCryptoServiceProvider
        ElseIf optTripleDES.Checked = True Then
            Return New TripleDESCryptoServiceProvider
        ElseIf optAES.Checked = True Then
            Return New RijndaelManaged
        ElseIf optRC2.Checked = True Then
            Return New RC2CryptoServiceProvider
        End If
    End Function

'Функція, що повертає ім'я файлу для шифрування
    Private Function GetFileName() As String
        If Text = "" Then
Repeat:
            If dlgS.ShowDialog = DialogResult.OK Then
                Text = dlgS.FileName
                Return dlgS.FileName
            Else
MsgBox ("You must create or select a file!", MsgBoxStyle.Exclamation)
                GoTo Repeat
            End If
        Else
            Return Text
        End If
    End Function

'Функція, перетворююча рядок в масив байтів
    Private Function ToBytes(ByVal s As String) As Byte()
        Dim enc As New UnicodeEncoding
        Return enc.GetBytes(s)
    End Function

'Функція, яка створює інтерфейс-шифратор
Private Function CreateEnc (ByVal AlgType As SymmetricAlgorithm) As ICryptoTransform
        If (TypeOf AlgType Is DESCryptoServiceProvider) Or _
            (TypeOf AlgType Is RC2CryptoServiceProvider) Then

            Return AlgType.CreateEncryptor(Key, IV)
ElseIf TypeOf AlgType Is TripleDESCryptoServiceProvider Then
            Return AlgType.CreateEncryptor(TripleKey, TripleIV)
        ElseIf TypeOf AlgType Is RijndaelManaged Then
            Return AlgType.CreateEncryptor(aesKey, aesIV)
        End If
    End Function

'Функція, яка створює інтерфейс-дешифратор
Private Function CreateDec (ByVal AlgType As SymmetricAlgorithm) As ICryptoTransform
        If (TypeOf AlgType Is DESCryptoServiceProvider) Or _
            (TypeOf AlgType Is RC2CryptoServiceProvider) Then

            Return AlgType.CreateDecryptor(Key, IV)
ElseIf TypeOf AlgType Is TripleDESCryptoServiceProvider Then
            Return AlgType.CreateDecryptor(TripleKey, TripleIV)
        ElseIf TypeOf AlgType Is RijndaelManaged Then
            Return AlgType.CreateDecryptor(aesKey, aesIV)
        End If
    End Function
#End Region
End Class

Отже, вийшов досить громіздкий код, але давайте спробуємо
розібратися в ньому і вловити найбільш важливі моменти. Для цього
переглянемо його зверху вниз. На самому початку оголошені 3 пари з ключів і
IV. Раніше не було необхідності це робити, оскільки ми тільки
шифрували дані, але не дешифрували. Це викликано тим, що навіть, якщо ми
самі не прописуємо провайдеру криптоалгоритму, що потрібно використовувати
такий-то ключ і такий-то IV, то він генерує їх самостійно як при
шифруванні, так і при дешифрування. У результаті ключі і IV,
згенеровані для шифрування і дешифрування, не збігаються, тобто
розшифрувати дані провайдер не зможе, і ви побачите вікно, подібне
рис. 6.

Частина 3   Криптографія asp net  0701201112000017669 min vs

Рис. 6 – Виняток, що виникає при розбіжності ключів або IV'ов
шифрування і дешифрування

Ключів і IV оголошено три пари. З коментарів видно, що перша
пара оголошена для DES і RC2, друга – для TripleDES і третя – для
AES / Rijndael. Навіщо ж це було зроблено? Зверніть увагу на довжину цих
масивів – вона скрізь різна. Справа в тому, що DES і RC2 використовують 8
байтові ключі і IV, TripleDES працює з 24 байтовий ключем і 8
байтовий IV, а Rijndael – з 32 байтовий ключем і 16 байтовий IV. З цих
даних вже можна робити сміливий висновок, що найбільш надійний метод – AES.

Т. к. для виконання кріптооперацій в цьому прикладі використовуються
файлові потоки, то для зручності звернення до цих файлів була додана
панель інструментів, за допомогою якої можна створювати, відкривати та
зберігати файли. За реалізацію цих можливостей відповідає наступна
процедура:

Private Sub tlb_ButtonClick (ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolBarButtonClickEventArgs) 
	Handles tlb.ButtonClick

Ми не будемо зупинятися на цьому місці, оскільки до шифрування воно
ніякого відношення не має, а "спустимося" далі за кодом до процедури
шифрування:

"Процедура шифрування
Private Sub cmdEncrypt_Click (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEncrypt.Click
Dim Alg As SymmetricAlgorithm = DefineAlg () 'Визначаємо алгоритм
        Dim Cryptor As ICryptoTransform = CreateEnc(Alg)
        Dim fs As New FileStream(GetFileName, FileMode.Create)
Dim CrStream As New CryptoStream (fs, Cryptor, CryptoStreamMode.Write)

'Отримуємо масив байтів
        Dim b() As Byte = ToBytes(txt1.Text)
'Шифруємо
        CrStream.Write(b, 0, b.Length)
'Закриваємо потік
        CrStream.Close()
        fs.Close()
        fs = Nothing


'Створюємо читач потоку
        fs = New FileStream(GetFileName, FileMode.Open)
        Dim sr As New StreamReader(fs, Encoding.Default)
'Показуємо результат
        txt2.Text = sr.ReadToEnd
'Закриваємо потоки
        sr.Close()
        fs.Close()

End SubЕслі
звернутися до лістингу 2.2, то там ми в першому рядку коду шифрування
створювали примірник конкретного криптопровайдера, зокрема –
DESCryptoServiceProvider. Тут ми використовуємо загальний клас, від якого
успадковуються всі класи-провайдери симетричних алгоритмів, –
SymmetricAlgorithm. Був застосований саме цей клас, тому що даний
приклад демонструє комбіноване шифрування / дешифрування, т. е.
забезпечує підтримку всіх доступних в. NET Framework симетричних
криптометоди: DES, TripleDES, AES / Rijndael, RC2.

Щоб визначити, який саме криптометоди використовується для
шифрування, викликається функція DefineAlg. Перейдемо до цієї функції:

'Функція, що повертає вибраний алгоритм
Private Function DefineAlg() As SymmetricAlgorithm
    If optDES.Checked = True Then
        Return New DESCryptoServiceProvider
    ElseIf optTripleDES.Checked = True Then
        Return New TripleDESCryptoServiceProvider
    ElseIf optAES.Checked = True Then
        Return New RijndaelManaged
    ElseIf optRC2.Checked = True Then
        Return New RC2CryptoServiceProvider
    End If
End Function

Як видно з лістингу, функція має тип SymmetricAlgorithm, але в
Залежно від обраного перемикача вона повертає новий екземпляр
відповідного об'єкта, тобто якщо вибраний був перемикач optDes, то
буде створено новий екземпляр класу DESCryptoServiceProvider.

Нагадаємо ще
раз, що класи DESCryptoServiceProvider,
TripleDESCryptoServiceProvider
, RijndaelManaged і
RC2CryptoServiceProvider
успадковуються від класу SymmetricAlgorithm
, Тому, не дивлячись на те, що функція має тип SymmetricAlgorithm,
вона може з тим же успіхом повертати екземпляр будь-якого з успадкованих
класів, що й було испльзовать у функції DefineAlg.

Визначивши алгоритм шифрування, додаток створює інтерфейс
трансформації, значення якого задається спеціально створеної для цього
функцією CreateEnc. В якості аргументу функція отримує
змінну Alg, Вона містить інформацію про обраний криптометоди.

У лістингу 2.2 для створення інтерфейсу-шифратора ми застосовували
наступний рядок:

 

Dim DES_Encryptor As
ICryptoTransform = DES.CreateEncryptor(DES.Key, DES.IV)

 

У лістингу 3.1 функція CreateEnc робить те ж саме, але вона
була створена лише через те, що в цьому прикладі використовуються кілька
криптометоди, а довжини ключів і IV у них різні, тому, щоб
визначити, яку пару ключ-IV потрібно використовувати, і була створена ця
функція. Якщо звернутися до її коду, то можна побачити, що вона лише
аналізує тип переданого класу і підставляє відповідний ключ і
IV.

Далі шифрування відбувається за тим же принципом, що і в лістингу
2.2 з тією лише відмінністю, що процес отримання масиву байтів винесено в
окрему функцію ToBytes:

'Функція, перетворююча рядок в масив байтів
Private Function ToBytes(ByVal s As String) As Byte()
    Dim enc As New UnicodeEncoding
    Return enc.GetBytes(s)
End 
Function

При створенні тестового додатку простежте за однією особливістю:
властивість Text форм

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*

*