1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
| using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Security.Cryptography;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
textBox1.ReadOnly = true;
textBox2.ReadOnly = true;
}
// Declare CspParmeters and RsaCryptoServiceProvider
// objects with global scope of your Form class.
CspParameters cspp = new CspParameters();
RSACryptoServiceProvider rsa;
// Path variables for source, encryption, and
// decryption folders. Must end with a backslash.
const string EncrFolder = @"c:\Encrypt\";
const string DecrFolder = @"c:\Decrypt\";
const string SrcFolder = @"c:\docs\";
// Public key file
const string PubKeyFile = @"c:\encrypt\rsaPublicKey.txt";
// Key container name for
// private/public key value pair.
const string keyName = "Key01";
private void buttonCreateAsmKeys_Click(object sender, System.EventArgs e)
{
// Stores a key pair in the key container.
cspp.KeyContainerName = keyName;
rsa = new RSACryptoServiceProvider(cspp);
rsa.PersistKeyInCsp = true;
if (rsa.PublicOnly == true)
label1.Text = "Ключ: " + cspp.KeyContainerName + " - Открытый";
else
label1.Text = "Ключ: " + cspp.KeyContainerName + " - Полная пара";
}
// Метод EncryptFile выполняет следующие действия.
//Создает симметричный алгоритм RijndaelManaged для шифрования содержимого.
//Создает объект RSACryptoServiceProvider и устанавливает для шифрования ключа RijndaelManaged.
//Использует объект CryptoStream для чтения и шифрования объекта FileStream исходного файла в виде байтовых блоков в объект назначения FileStream для зашифрованного файла.
//Определяет длину зашифрованного ключа и вектора инициализации и создает байтовые массивы соответствующей длины.
//Записывает ключ, вектор инициализации и значения их длин в пакет шифрования.
//Пакетом шифрования используется следующий формат.
//длина ключа, байты 0-3
//длина вектора инициализации, байты 4-7
//зашифрованный ключ
//вектор инициализации
//зашифрованный текст
private void buttonEncryptFile_Click(object sender, System.EventArgs e)
{
if (rsa == null)
MessageBox.Show("Не найден ключ");
else
{
// Display a dialog box to select a file to encrypt.
openFileDialog1.InitialDirectory = SrcFolder;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string fName = openFileDialog1.FileName;
if (fName != null)
{
FileInfo fInfo = new FileInfo(fName);
// Pass the file name without the path.
string name = fInfo.FullName;
EncryptFile(name);
textBox1.Text = name;
}
}
}
}
private void EncryptFile(string inFile)
{
// Create instance of Rijndael for
// symetric encryption of the data.
//RijndaelManaged rjndl = new RijndaelManaged();
//rjndl.KeySize = 256;
//rjndl.BlockSize = 256;
//rjndl.Mode = CipherMode.CBC;
//ICryptoTransform transform = rjndl.CreateEncryptor();
TripleDESCryptoServiceProvider TripleD = new TripleDESCryptoServiceProvider();
TripleD.KeySize = 128;
TripleD.BlockSize = 64;
TripleD.Mode = CipherMode.CBC;
TripleD.Padding = PaddingMode.ISO10126;
ICryptoTransform transform1 = TripleD.CreateEncryptor();
// Use RSACryptoServiceProvider to
// enrypt the Rijndael key.
// rsa is previously instantiated:
// rsa = new RSACryptoServiceProvider(cspp);
byte[] keyEncrypted = rsa.Encrypt(TripleD.Key, false);
// Создание массива байтов для ключа и вектора инициализации.
byte[] LenK = new byte[4];
byte[] LenIV = new byte[4];
int lKey = keyEncrypted.Length;
LenK = BitConverter.GetBytes(lKey);
int lIV = TripleD.IV.Length;
LenIV = BitConverter.GetBytes(lIV);
// Write the following to the FileStream
// for the encrypted file (outFs):
// - length of the key
// - length of the IV
// - ecrypted key
// - the IV
// - the encrypted cipher content
int startFileName = inFile.LastIndexOf("\\") + 1;
// Change the file's extension to ".enc"
string outFile = EncrFolder + inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + ".enc";
using (FileStream outFs = new FileStream(outFile, FileMode.Create))
{
outFs.Write(LenK, 0, 4);
outFs.Write(LenIV, 0, 4);
outFs.Write(keyEncrypted, 0, lKey);
outFs.Write(TripleD.IV, 0, lIV);
// Now write the cipher text using
// a CryptoStream for encrypting.
using (CryptoStream outStreamEncrypted = new CryptoStream(outFs, transform1, CryptoStreamMode.Write))
{
// By encrypting a chunk at
// a time, you can save memory
// and accommodate large files.
int count = 0;
int offset = 0;
// blockSizeBytes can be any arbitrary size.
int blockSizeBytes = TripleD.BlockSize / 8;
byte[] data = new byte[blockSizeBytes];
int bytesRead = 0;
using (FileStream inFs = new FileStream(inFile, FileMode.Open))
{
do
{
count = inFs.Read(data, 0, blockSizeBytes);
offset += count;
outStreamEncrypted.Write(data, 0, count);
bytesRead += blockSizeBytes;
}
while (count > 0);
inFs.Close();
}
outStreamEncrypted.FlushFinalBlock();
outStreamEncrypted.Close();
}
outFs.Close();
}
}
// Метод Decrypt выполняет следующие действия.
//Создает симметричный алгоритм RijndaelManaged для расшифровки содержимого.
//Считывает первые восемь байтов объекта FileStream зашифрованного пакета в байтовые массивы
//для получения значений длин зашифрованного ключа и вектора инициализации.
//Извлекает ключ и вектор инициализации из пакета шифрования в байтовые массивы.
//Создает объект RSACryptoServiceProvider и устанавливает для расшифровки ключа RijndaelManaged.
//Использует объект CryptoStream для чтения и расшифровки зашифрованного текста пакета шифрования
//FileStream в виде байтовых блоков и загрузки их в объект FileStream для расшифрованного файла.
//По завершении этой операции расшифровка считается выполненной.
private void buttonDecryptFile_Click(object sender, EventArgs e)
{
if (rsa == null)
MessageBox.Show("Key not set.");
else
{
// Display a dialog box to select the encrypted file.
openFileDialog2.InitialDirectory = EncrFolder;
if (openFileDialog2.ShowDialog() == DialogResult.OK)
{
string fName = openFileDialog2.FileName;
if (fName != null)
{
FileInfo fi = new FileInfo(fName);
string name = fi.Name;
DecryptFile(name);
}
}
}
}
private void DecryptFile(string inFile)
{
// Create instance of Rijndael for
// symetric decryption of the data.
//RijndaelManaged rjndl = new RijndaelManaged();
//rjndl.KeySize = 256;
//rjndl.BlockSize = 256;
//rjndl.Mode = CipherMode.CBC;
TripleDESCryptoServiceProvider TripleD = new TripleDESCryptoServiceProvider();
TripleD.KeySize = 128;
TripleD.BlockSize = 64;
TripleD.Mode = CipherMode.CBC;
// TripleD.Padding = PaddingMode.ISO10126;
// ICryptoTransform transform1 = TripleD.CreateEncryptor();
// Create byte arrays to get the length of
// the encrypted key and IV.
// These values were stored as 4 bytes each
// at the beginning of the encrypted package.
byte[] LenK = new byte[4];
byte[] LenIV = new byte[4];
// Consruct the file name for the decrypted file.
string outFile = DecrFolder + inFile.Substring(0, inFile.LastIndexOf(".")) + ".txt";
// Use FileStream objects to read the encrypted
// file (inFs) and save the decrypted file (outFs).
using (FileStream inFs = new FileStream(EncrFolder + inFile, FileMode.Open))
{
inFs.Seek(0, SeekOrigin.Begin);
inFs.Seek(0, SeekOrigin.Begin);
inFs.Read(LenK, 0, 3);
inFs.Seek(4, SeekOrigin.Begin);
inFs.Read(LenIV, 0, 3);
// Convert the lengths to integer values.
int lenK = BitConverter.ToInt32(LenK, 0);
int lenIV = BitConverter.ToInt32(LenIV, 0);
// Determine the start postition of
// the ciphter text (startC)
// and its length(lenC).
int startC = lenK + lenIV + 8;
int lenC = (int)inFs.Length - startC;
// Create the byte arrays for
// the encrypted Rijndael key,
// the IV, and the cipher text.
byte[] KeyEncrypted = new byte[lenK];
byte[] IV = new byte[lenIV];
// Extract the key and IV
// starting from index 8
// after the length values.
inFs.Seek(8, SeekOrigin.Begin);
inFs.Read(KeyEncrypted, 0, lenK);
inFs.Seek(8 + lenK, SeekOrigin.Begin);
inFs.Read(IV, 0, lenIV);
Directory.CreateDirectory(DecrFolder);
// Use RSACryptoServiceProvider
// to decrypt the Rijndael key.
byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false);
// Decrypt the key.
ICryptoTransform transform = TripleD.CreateDecryptor(KeyDecrypted, IV);
// Decrypt the cipher text from
// from the FileSteam of the encrypted
// file (inFs) into the FileStream
// for the decrypted file (outFs).
using (FileStream outFs = new FileStream(outFile, FileMode.Create))
{
int count = 0;
int offset = 0;
// blockSizeBytes can be any arbitrary size.
int blockSizeBytes = TripleD.BlockSize / 8;
byte[] data = new byte[blockSizeBytes];
// By decrypting a chunk a time,
// you can save memory and
// accommodate large files.
// Start at the beginning
// of the cipher text.
inFs.Seek(startC, SeekOrigin.Begin);
using (CryptoStream outStreamDecrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
{
do
{
count = inFs.Read(data, 0, blockSizeBytes);
offset += count;
outStreamDecrypted.Write(data, 0, count);
}
while (count > 0);
outStreamDecrypted.FlushFinalBlock();
outStreamDecrypted.Close();
}
outFs.Close();
}
inFs.Close();
}
}
//Экспорт открытого ключа
// В рамках этой задачи ключ, созданный при нажатии кнопки Create Keys, сохраняется в файл. Экспортируются только открытые параметры.
//Данная задача воссоздает ситуацию, в которой Алиса предоставляет Бобу открытый ключ, чтобы он мог зашифровывать для нее файлы. Боб и другие лица, имеющие открытый ключ, не смогут расшифровывать их, поскольку они не имеют полной пары ключей с закрытыми параметрами.
void buttonExportPublicKey_Click(object sender, System.EventArgs e)
{
// Save the public key created by the RSA
// to a file. Caution, persisting the
// key to a file is a security risk.
Directory.CreateDirectory(EncrFolder);
StreamWriter sw = new StreamWriter(PubKeyFile, false);
sw.Write(rsa.ToXmlString(false));
sw.Close();
}
//Импорт открытого ключа
// В рамках данной задачи производится загрузка ключа, имеющего только открытые параметры, который затем устанавливается в качестве имени контейнера ключа. Этот ключ создается при нажатии кнопки Export Public Key.
//Данная задача воссоздает ситуацию, в которой Боб загружает ключ Алисы, имеющий только открытые параметры, чтобы зашифровывать для нее файлы.
void buttonImportPublicKey_Click(object sender, System.EventArgs e)
{
StreamReader sr = new StreamReader(PubKeyFile);
cspp.KeyContainerName = keyName;
rsa = new RSACryptoServiceProvider(cspp);
string keytxt = sr.ReadToEnd();
rsa.FromXmlString(keytxt);
rsa.PersistKeyInCsp = true;
if (rsa.PublicOnly == true)
label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only";
else
label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair";
sr.Close();
}
// Получение закрытого ключа
//В рамках этой задачи контейнеру ключа присваивается имя, соответствующее имени ключа, созданного при нажатии кнопки Create Keys. Контейнер ключа будет содержать полную пару ключей с закрытыми параметрами.
//Данная задача воссоздает ситуацию, в которой Алиса использует свой закрытый ключ для расшифровки файлов, зашифрованных Бобом.
private void buttonGetPrivateKey_Click(object sender, EventArgs e)
{
cspp.KeyContainerName = keyName;
rsa = new RSACryptoServiceProvider(cspp);
rsa.PersistKeyInCsp = true;
if (rsa.PublicOnly == true)
label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only";
else
label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair";
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
}
}
} |