В этом примере мы напишем программу на языке C# для шифрования и дешифрования данных с помощью симметричного ключа
Что такое симметричный ключ?
Алгоритмы с симметричным ключом — это алгоритмы для криптографии, которые используют одни и те же криптографические ключи как для шифрования открытого текста, так и для расшифровки зашифрованного текста. Ключи могут быть идентичны или может быть простое преобразование, чтобы перейти между этими двумя ключами.
Реализация C# для шифрования и дешифрования данных с помощью симметричного ключа :
В приведенной ниже реализации мы будем использовать алгоритм Rijndael для шифрования и расшифровки данных в C#. Ниже приведены несколько ключевых параметров, которые мы будем использовать в реализации C#.
— парольная фраза: парольная фраза, из которой будет выведен псевдослучайный пароль. Полученный пароль будет использоваться для создания ключа шифрования. Парольная фраза может быть любой строкой.
— saltValue: значение соли, используемое вместе с парольной фразой для создания пароля. Соль может быть любой строкой.
— hashAlgorithm: алгоритм хэширования, используемый для генерации пароля. Допустимые значения: «MD5″ и » SHA256”
passwordIterations: количество итераций, используемых для создания пароля. Одной или двух итераций должно быть достаточно.
— initVector: вектор инициализации (или IV). Это значение необходимо для шифрования первого блока текстовых данных. Для RijndaelManaged class IV должно быть ровно 16 символов ASCII длиной.
— keySize: размер ключа шифрования в битах. Допустимые значения: 128, 192 и 256.
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 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; public class RijndaelAlgorithm { public static string Encrypt ( string plainText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize ) { //Преобразование строк в байтовые массивы. //Предположим, что строки содержат только коды ASCII. //Если строки содержат символы Юникода, используйте Юникод, UTF7 или UTF8 //Кодировки. byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); //Преобразование открытого текста в массив байтов. byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); // Во-первых, мы должны создать пароль, из которого будет получен ключ. //Этот пароль будет создан из указанной парольной фразы и //соли. Пароль будет создан с использованием указанного хэша //алгоритма. Создание пароля может выполняться в нескольких итерациях. PasswordDeriveBytes password = new PasswordDeriveBytes ( passPhrase, saltValueBytes, hashAlgorithm, passwordIterations ); //Используйте пароль для создания псевдослучайных байтов для шифрования //ключа. Укажите размер ключа в байтах (вместо битов). byte[] keyBytes = password.GetBytes(keySize / 8); //Создать неинициализированный объект шифрования Rijndael. RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; //Создать шифратор из существующих байтов ключа и инициализации //вектор. Размер ключа определяется на основе количества байтов ключа. ICryptoTransform encryptor = symmetricKey.CreateEncryptor ( keyBytes, initVectorBytes ); //Определите поток памяти, который будет использоваться для хранения зашифрованных данных. MemoryStream memoryStream = new MemoryStream(); //Определите криптографический поток (всегда используйте режим записи для шифрования). CryptoStream cryptoStream = new CryptoStream ( memoryStream, encryptor, CryptoStreamMode.Write ); //Начните шифровать. cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); //Шифровка конца. cryptoStream.FlushFinalBlock(); //Преобразование зашифрованных данных из потока памяти в массив байтов. byte[] cipherTextBytes = memoryStream.ToArray(); //Закройте оба потока. memoryStream.Close(); cryptoStream.Close(); //Преобразование зашифрованных данных в строку в кодировке base64. string cipherText = Convert.ToBase64String(cipherTextBytes); //Возвратите зашифрованную последовательность. return cipherText; } public static string Decrypt ( string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize ) { //Преобразование строк, определяющих характеристики ключа шифрования, в байтовые массивы. byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); //Преобразование нашего зашифрованного текста в массив байтов. byte[] cipherTextBytes = Convert.FromBase64String(cipherText); //Во-первых, мы должны создать пароль, из которого будет получен ключ //Этот пароль будет создан из указанной парольной фразы и значения соли. //Пароль будет создан с использованием указанного алгоритма хэша. Создание пароля может выполняться в нескольких итерациях. PasswordDeriveBytes password = new PasswordDeriveBytes ( passPhrase, saltValueBytes, hashAlgorithm, passwordIterations ); //Используйте пароль для создания псевдослучайных байтов для шифрования //ключа. Укажите размер ключа в байтах (вместо битов). byte[] keyBytes = password.GetBytes(keySize / 8); //Создать неинициализированный объект шифрования Rijndael. RijndaelManaged symmetricKey = new RijndaelManaged(); //Целесообразно установить режим шифрования "Цепочка блоков шифрования" //(CBC). Используйте параметры по умолчанию для других симметричных ключевых параметров. symmetricKey.Mode = CipherMode.CBC; //Создать дешифратор из существующих байтов ключа и инициализации //вектора. Размер ключа определяется на основе номера ключа //байты. ICryptoTransform decryptor = symmetricKey.CreateDecryptor ( keyBytes, initVectorBytes ); //Определите поток памяти, который будет использоваться для хранения зашифрованных данных. MemoryStream memoryStream = new MemoryStream(cipherTextBytes); //Определите криптографический поток (всегда используйте режим чтения для шифрования). CryptoStream cryptoStream = new CryptoStream ( memoryStream, decryptor, CryptoStreamMode.Read ); byte[] plainTextBytes = new byte[cipherTextBytes.Length]; //Начните расшифровывать. int decryptedByteCount = cryptoStream.Read ( plainTextBytes, 0, plainTextBytes.Length ); //Закройте оба потока. memoryStream.Close(); cryptoStream.Close(); //Преобразование расшифрованных данных в строку. //Предположим, что исходная строка открытого текста была UTF8-encoded. string plainText = Encoding.UTF8.GetString ( plainTextBytes, 0, decryptedByteCount ); //Возвратите расшифрованную последовательность. return plainText; } } /// Иллюстрирует использование класса RijndeavelSimple для шифрования и дешифрования данных. public class RijndaelSimpleTest { /// <summary> /// Основная точка входа для приложения. /// </summary> [STAThread] static void Main(string[] args) { Console.Write("Введите исходный текст: : "); string plainText = Console.ReadLine(); string passPhrase = "TestPassphrase"; //Может быть любой строкой string saltValue = "TestSaltValue"; // Может быть любой строкой string hashAlgorithm = "SHA256"; // может быть "MD5" int passwordIterations = 2; //Может быть любым числом string initVector = "!1A3g2D4s9K556g7"; // Должно быть 16 байт int keySize = 256; // Может быть 192 или 128 Console.WriteLine(String.Format(" Незашифрованный текст : {0}", plainText)); string cipherText = RijndaelAlgorithm.Encrypt ( plainText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize ); Console.WriteLine(String.Format("Зашифрованный : {0}", cipherText)); plainText = RijndaelAlgorithm.Decrypt ( cipherText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize ); Console.WriteLine(String.Format("Дешифрованный : {0}", plainText)); Console.ReadKey(); } } |
1
Вывод:
Введите исходный текст: : nookery.ru
Незашифрованный текст : nookery.ru
Зашифрованный : FTcXcEFffsPCZd0UKxBUTA==
Дешифрованный : nookery.ru