В этом примере мы напишем программу на языке C# для шифрования и дешифрования данных с помощью симметричного ключа
Что такое симметричный ключ?
Алгоритмы с симметричным ключом — это алгоритмы для криптографии, которые используют одни и те же криптографические ключи как для шифрования открытого текста, так и для расшифровки зашифрованного текста. Ключи могут быть идентичны или может быть простое преобразование, чтобы перейти между этими двумя ключами.
Реализация C# для шифрования и дешифрования данных с помощью симметричного ключа :
В приведенной ниже реализации мы будем использовать алгоритм Rijndael для шифрования и расшифровки данных в C#. Ниже приведены несколько ключевых параметров, которые мы будем использовать в реализации C#.
— парольная фраза: парольная фраза, из которой будет выведен псевдослучайный пароль. Полученный пароль будет использоваться для создания ключа шифрования. Парольная фраза может быть любой строкой.
— saltValue: значение соли, используемое вместе с парольной фразой для создания пароля. Соль может быть любой строкой.
— hashAlgorithm: алгоритм хэширования, используемый для генерации пароля. Допустимые значения: «MD5″ и » SHA256”
passwordIterations: количество итераций, используемых для создания пароля. Одной или двух итераций должно быть достаточно.
— initVector: вектор инициализации (или IV). Это значение необходимо для шифрования первого блока текстовых данных. Для RijndaelManaged class IV должно быть ровно 16 символов ASCII длиной.
— keySize: размер ключа шифрования в битах. Допустимые значения: 128, 192 и 256.
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