using System; using System.IO; using System.Text; using System.IO.Compression; using System.Xml.Serialization; using System.Security.Cryptography; using System.Text.RegularExpressions; namespace Library.Cryptography { public class CryptoDB { public GZipStream gzip = null; //Поток для сжатия gzip public MemoryStream ms = null; //Поток для отдачи класса public StreamReader sr = null; //Поток для отдачи класса public CryptoStream crypt = null; //Криптография данных public void Dispose() { if (crypt != null) { try { crypt.FlushFinalBlock(); } catch { } crypt = null; } if (gzip != null) { try { gzip.Close(); gzip.Dispose(); gzip = null; } catch { } } if (ms != null) { try { ms.Close(); ms.Dispose(); ms = null; } catch { } } if (sr != null) { try { sr.Close(); sr.Dispose(); sr = null; } catch { } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////############# Временные данные для обработки запросов криптографии #############///// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private static Rijndael aes = CreateAES(); //Ключ AES256 private static string dir = Environment.CurrentDirectory + @"\tmp\"; //Дириктория private static Rijndael CreateAES(string key = "defaultAESkey256") { byte[] IVa = new byte[] { 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x11, 0x12, 0x13, 0x14, 0x0e, 0x16, 0x17 }; Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(Encoding.UTF8.GetString(IVa, 0, IVa.Length), Encoding.UTF8.GetBytes(key)); Rijndael _aes = new RijndaelManaged(); _aes.Key = deriveBytes.GetBytes(256 / 16); _aes.IV = _aes.Key; IVa = null; deriveBytes = null; return _aes; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////############# Работа с данными, запись данных в файл, формат xml #############///// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Имя базы /// Данные для сохранения /// Криптовать содержимое файла или нет /// Прятать имя базы данных под md5 public static void Write(string dbName, object data, bool crypto = true, bool MD5 = false) { try { //Путь к файлу xml string FileCry = (dir + (MD5 ? md5.text(dbName) : dbName)); //Создаем каталог для данных Directory.CreateDirectory(dir); //Записываем файл File.WriteAllBytes(FileCry, Write(data, crypto)); //Создаем бекап файла File.Copy(FileCry, (dir + (MD5 ? md5.text(dbName + ".tmp") : (dbName + ".tmp"))), true); //Чистим ресурсы FileCry = null; } catch { } //Чистим ресурсы dbName = null; data = null; } /// Данные для конвертирования в byte[] /// Криптовать содержимое файла или нет public static byte[] Write(object data, bool crypto = true) { //Класс для работы с данными CryptoDB cryptoDB = new CryptoDB(); byte[] res = null; try { //Создаем xml в виде String XmlSerializer xmlSerializer = new XmlSerializer(data.GetType()); StringWriter textWriter = new StringWriter(); xmlSerializer.Serialize(textWriter, data); //Создаем xml формат if (crypto) { //Записываем криптованную базу xml cryptoDB.ms = new MemoryStream(); //Поток для записи данных в файл cryptoDB.crypt = new CryptoStream(cryptoDB.ms, aes.CreateEncryptor(), CryptoStreamMode.Write); //Записывает шифрованные данные в поток ms cryptoDB.gzip = new GZipStream(cryptoDB.crypt, CompressionMode.Compress); //Запаковываем в gzip //Записываем в поток все данные byte[] mass = Encoding.UTF8.GetBytes(textWriter.ToString()); cryptoDB.gzip.Write(mass, 0, mass.Length); //Чистим ресурсы cryptoDB.gzip.Close(); cryptoDB.gzip.Dispose(); cryptoDB.gzip = null; cryptoDB.crypt.Close(); cryptoDB.crypt.Dispose(); cryptoDB.crypt = null; mass = null; //Записываем результат res = cryptoDB.ms.ToArray(); } else { //Записываем не криптованную базу xml res = Encoding.UTF8.GetBytes(textWriter.ToString()); } //Чистим ресурсы textWriter.Close(); textWriter.Flush(); textWriter.Dispose(); textWriter = null; xmlSerializer = null; } catch { } //Чистим ресурсы cryptoDB.Dispose(); cryptoDB = null; data = null; return res; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////############# Работа с данными, чтение данных из файла в формате json #############///// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Сериализация /// Имя базы /// Расшифровывать содержимое файла или нет /// Имя файла указанно в формате md5 public static T Read(string dbName, bool crypto = true, bool MD5 = false) where T : new() { T result = default(T); try { string FileCry = (dir + (MD5 ? md5.text(dbName) : dbName)); Reset: result = Read(File.ReadAllBytes(FileCry), crypto); if (result == null) { //Берем данные из бекапа if (FileCry != (dir + (MD5 ? md5.text(dbName + ".tmp") : (dbName + ".tmp")))) { FileCry = (dir + (MD5 ? md5.text(dbName + ".tmp") : (dbName + ".tmp"))); goto Reset; } } //Чистим ресурсы FileCry = null; } catch { } //Чистим ресурсы и возвращаем результат dbName = null; return (result == null ? new T() : result); } /// Сериализация /// Содержимое для конвертации в класс /// Расшифровывать содержимое или нет public static T Read(byte[] sourse, bool crypto = true, bool EroorNull = false) where T : new() { //Класс для работы с данными CryptoDB cryptoDB = new CryptoDB(); T result = default(T); try { XmlSerializer deserializer = new XmlSerializer(typeof(T)); if (crypto) { //Считываем криптованную базу xml cryptoDB.ms = new MemoryStream(sourse); //Считываем массив cryptoDB.crypt = new CryptoStream(cryptoDB.ms, aes.CreateDecryptor(), CryptoStreamMode.Read); //Расшифровываем массив cryptoDB.gzip = new GZipStream(cryptoDB.crypt, CompressionMode.Decompress, true); //Распаковываем gzip cryptoDB.sr = new StreamReader(cryptoDB.gzip); //хз, но получаем типа string result = (T)deserializer.Deserialize(cryptoDB.sr); //Возвращаем класс после обработчки xml } else { //Считываем не криптованную базу xml cryptoDB.ms = new MemoryStream(sourse); TextReader textReader = new StreamReader(cryptoDB.ms); result = (T)deserializer.Deserialize(textReader); textReader.Close(); textReader.Dispose(); textReader = null; } deserializer = null; } catch { } //Чистим ресурсы и возвращаем результат cryptoDB.Dispose(); cryptoDB = null; sourse = null; if (EroorNull) { return result; } else { return (result == null ? new T() : result); } } } }