diff --git a/anbs_cp/Classes/Encrypt/PasswordEncrypt.cs b/anbs_cp/Classes/Encrypt/PasswordEncrypt.cs new file mode 100644 index 0000000..7270784 --- /dev/null +++ b/anbs_cp/Classes/Encrypt/PasswordEncrypt.cs @@ -0,0 +1,56 @@ +using System.Text; + +using anbs_cp.Interfaces; + +using Microsoft.AspNetCore.Cryptography.KeyDerivation; + +namespace anbs_cp.Classes.Encrypt; + +/// +/// Класс шифрования пароля +/// +public sealed class PasswordEncrypt: IEncryptor +{ + /// + /// Шифрование пароля + /// + /// Пароль + /// Хэш-код пароля + /// Зашифрованный пароль + public string Encrypt (string password, string salt) + { + // Получаю byte-массив из хэш-кода пароля + byte[] saltBytes = Encoding.UTF8.GetBytes(salt); + + // Шифрую пароль + byte[] encryptedPassword = KeyDerivation.Pbkdf2(password, saltBytes, KeyDerivationPrf.HMACSHA512, 5000, 64); + + // Возвращаю зашифрованный пароль + return Convert.ToBase64String(encryptedPassword); + } + + /// + /// Этот метод не требует реализации в этом классе! + /// + /// НЕ РАБОТАЕТ + /// НЕ РАБОТАЕТ + /// НЕ РАБОТАЕТ + /// Этот метод не требует реализации в этом классе! + public string Decrypt (string encryptedValue, string salt) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!"); + + /// + /// Этот метод не требует реализации в этом классе! + /// + /// НЕ РАБОТАЕТ + /// НЕ РАБОТАЕТ + /// Этот метод не требует реализации в этом классе! + public string Base64UrlEncode (string text) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!"); + + /// + /// Этот метод не требует реализации в этом классе! + /// + /// НЕ РАБОТАЕТ + /// НЕ РАБОТАЕТ + /// Этот метод не требует реализации в этом классе! + public string Base64UrlDecode (string text) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!"); +} \ No newline at end of file diff --git a/anbs_cp/Classes/Encrypt/StringEncrypt.cs b/anbs_cp/Classes/Encrypt/StringEncrypt.cs index 46a90cd..1a96540 100644 --- a/anbs_cp/Classes/Encrypt/StringEncrypt.cs +++ b/anbs_cp/Classes/Encrypt/StringEncrypt.cs @@ -1,56 +1,17 @@ -using System.Security.Cryptography; -using System.Text; - -namespace anbs_cp.Classes.Encrypt; +namespace anbs_cp.Classes.Encrypt; /// -/// Класс для шифровки строк +/// Статическая обертка для класса шифровки строк StringEncryptor /// public static class StringEncrypt { - /// - /// Получение ключа из строки - /// - /// Ключ-строка - /// Хэш-ключ - /// Ключ - private static byte[] KeyFromString (string s, byte[] salt) - { - // Создаю хэшер - using Rfc2898DeriveBytes hasher = new(s, salt, 1000, HashAlgorithmName.SHA256); - - // Получаю ключ - return hasher.GetBytes(32); - } - /// /// Метод для шифрования строки /// /// Строка, которая должна быть зашифрована /// Ключ /// Этот статический метод возвращает зашифрованную строку - public static string Encrypt (string text, string key) - { - // Создаю криптограф - using Aes aes = Aes.Create(); - - // Получаю ключ - aes.Key = KeyFromString(key, aes.IV); - - // Открываю поток - using MemoryStream ms = new(); - - // Пишу данные в поток - ms.Write(aes.IV); - - // Создаю шифрованный поток - using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true)) - // Пишу данные в него - cs.Write(Encoding.UTF8.GetBytes(text)); - - // Возвращаю зашифрованный текст - return Convert.ToBase64String(ms.ToArray()); - } + public static string Encrypt (string text, string key) => new StringEncryptor().Encrypt(text, key); /// /// Метод для дешифрования строки @@ -58,63 +19,19 @@ public static class StringEncrypt /// Строка, которая должна быть дешифрована /// Ключ /// Этот статический метод возвращает дешифрованную строку - public static string Decrypt (string text, string key) - { - // Открываю поток в памяти - using MemoryStream ms = new(Convert.FromBase64String(text)); - - // Задаю ключ - byte[] iv = new byte[16]; - - // Читаю его - _ = ms.Read(iv); - - // Создаю криптограф - using Aes aes = Aes.Create(); - - // Получаю ключ - aes.Key = KeyFromString(key, iv); - - // присваиваю ключ - aes.IV = iv; - - // Создаю поток дешифратора - using CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true); - - // Задаю поток итогового текста - using MemoryStream output = new(); - - // Копирую данные в выходной поток - cs.CopyTo(output); - - // Вывожу расшифрованный текст - return Encoding.UTF8.GetString(output.ToArray()); - } + public static string Decrypt (string text, string key) => new StringEncryptor().Decrypt(text, key); /// /// Декодирует зашифрованную строку в HTML-пригодный формат /// /// Зашифрованная строка /// Этот статический метод возвращает дешифрованную строку - public static string Base64UrlEncode(string text) => text.TrimEnd('=').Replace('+', '-').Replace('/', '_'); + public static string Base64UrlEncode (string text) => new StringEncryptor().Base64UrlEncode(text); /// /// Раскодирует из декодированной строки в HTML-пригодный формат /// /// Декодированная строка /// Этот статический метод возвращает шифрованную строку - public static string Base64UrlDecode(string text) - { - string result = text.Replace('_', '/').Replace('-', '+'); - switch (result.Length % 4) - { - case 2: - result += "=="; - break; - case 3: - result += "="; - break; - } - return result; - } + public static string Base64UrlDecode (string text) => new StringEncryptor().Base64UrlDecode(text); } \ No newline at end of file diff --git a/anbs_cp/Classes/Encrypt/StringEncryptor.cs b/anbs_cp/Classes/Encrypt/StringEncryptor.cs new file mode 100644 index 0000000..4f6cce8 --- /dev/null +++ b/anbs_cp/Classes/Encrypt/StringEncryptor.cs @@ -0,0 +1,127 @@ +using System.Security.Cryptography; +using System.Text; + +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes.Encrypt; + +/// +/// Класс для шифровки строк +/// +public sealed class StringEncryptor: IEncryptor +{ + /// + /// Получение ключа из строки + /// + /// Ключ-строка + /// Хэш-ключ + /// Ключ + private static byte[] KeyFromString (string s, byte[] salt) + { + // Создаю хэшер + using Rfc2898DeriveBytes hasher = new(s, salt, 1000, HashAlgorithmName.SHA256); + + // Получаю ключ + return hasher.GetBytes(32); + } + + /// + /// Метод для шифрования строки + /// + /// Строка, которая должна быть зашифрована + /// Ключ + /// Этот метод возвращает зашифрованную строку + public string Encrypt (string value, string salt) + { + // Создаю криптограф + using Aes aes = Aes.Create(); + + // Получаю ключ + aes.Key = KeyFromString(salt, aes.IV); + + // Открываю поток + using MemoryStream ms = new(); + + // Пишу данные в поток + ms.Write(aes.IV); + + // Создаю шифрованный поток + using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true)) + // Пишу данные в него + cs.Write(Encoding.UTF8.GetBytes(value)); + + // Возвращаю зашифрованный текст + return Convert.ToBase64String(ms.ToArray()); + } + + /// + /// Метод для дешифрования строки + /// + /// Строка, которая должна быть дешифрована + /// Ключ + /// Этот метод возвращает дешифрованную строку + public string Decrypt (string encryptedValue, string salt) + { + // Открываю поток в памяти + using MemoryStream ms = new(Convert.FromBase64String(encryptedValue)); + + // Задаю ключ + byte[] iv = new byte[16]; + + // Читаю его + _ = ms.Read(iv); + + // Создаю криптограф + using Aes aes = Aes.Create(); + + // Получаю ключ + aes.Key = KeyFromString(salt, iv); + + // присваиваю ключ + aes.IV = iv; + + // Создаю поток дешифратора + using CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true); + + // Задаю поток итогового текста + using MemoryStream output = new(); + + // Копирую данные в выходной поток + cs.CopyTo(output); + + // Вывожу расшифрованный текст + return Encoding.UTF8.GetString(output.ToArray()); + } + + /// + /// Декодирует зашифрованную строку в HTML-пригодный формат + /// + /// Зашифрованная строка + /// Этот метод возвращает дешифрованную строку + public string Base64UrlEncode (string text) => text.TrimEnd('=').Replace('+', '-').Replace('/', '_'); + + /// + /// Раскодирует из декодированной строки в HTML-пригодный формат + /// + /// Декодированная строка + /// Этот метод возвращает шифрованную строку + public string Base64UrlDecode (string text) + { + // Первоначальная замена + string result = text.Replace('_', '/').Replace('-', '+'); + + // Заменяю значения + switch (result.Length % 4) + { + case 2: + result += "=="; + break; + case 3: + result += "="; + break; + } + + // Возвращаю результат + return result; + } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/IEncryptor.cs b/anbs_cp/Interfaces/IEncryptor.cs new file mode 100644 index 0000000..4fb84ea --- /dev/null +++ b/anbs_cp/Interfaces/IEncryptor.cs @@ -0,0 +1,37 @@ +namespace anbs_cp.Interfaces; + +/// +/// Интерфейс шифрования +/// +public interface IEncryptor +{ + /// + /// Метод для шифрования строки + /// + /// Строка, которая должна быть зашифрована + /// Ключ шифрования + /// Этот метод возвращает зашифрованную строку + string Encrypt (string value, string salt); + + /// + /// Метод для дешифрования строки + /// + /// Строка, которая должна быть дешифрована + /// Ключ шифрования + /// Этот метод возвращает дешифрованную строку + string Decrypt (string encryptedValue, string salt); + + /// + /// Декодирует зашифрованную строку в HTML-пригодный формат + /// + /// Зашифрованная строка + /// Этот метод возвращает дешифрованную строку + string Base64UrlEncode (string text); + + /// + /// Раскодирует из декодированной строки в HTML-пригодный формат + /// + /// Декодированная строка + /// Этот метод возвращает шифрованную строку + string Base64UrlDecode (string text); +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 95cc409..17e5ea1 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.902.0 + 2023.908.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# @@ -38,6 +38,7 @@ + all diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 25bcf0b..94e58b5 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -8,6 +8,7 @@ True True True + True True True True