• XSS.stack #1 – первый литературный журнал от юзеров форума

[C#] Шифрование строк методом RSA

r3xq1

(L3) cache
Пользователь
Регистрация
14.01.2020
Сообщения
233
Реакции
146
Простенький способ зашифровать строки методом RSA (1024/2048)
Создаём класс RSATool.cs и запишем в него код:
C#:
namespace OldLockerTestEncTools
{
    using System;
    using System.Collections.Generic;
    using System.Security.Cryptography;
    using System.Text;

    public class RSATool
    {
        /// <summary>
        /// Метод для шифрования текста <b>"Публичным ключём"</b>
        /// </summary>
        /// <param name="strText">Текст для шифрования</param>
        /// <param name="KeySize">Размер публичного ключа RSA</param>
        /// <param name="strPublicKey">Публичный ключ RSA</param>
        /// <returns>Шифрованный текст</returns>
        public string Encrypt(string strText, int KeySize, string strPublicKey)
        {
            using (var rsa = new RSACryptoServiceProvider(KeySize))
            {
                rsa.FromXmlString(strPublicKey);

                byte[] byteText = Encoding.UTF8.GetBytes(strText);
                byte[] byteEntry = rsa.Encrypt(byteText, false);

                return Convert.ToBase64String(byteEntry);
            }
        }

        /// <summary>
        /// Метод для расшифровки текста <b>"Приватным ключём"</b>
        /// </summary>
        /// <param name="strEntryText">Текст для расшифровки</param>
        /// <param name="KeySize">Размер приватного ключа RSA</param>
        /// <param name="strPrivateKey">Приватный ключ RSA</param>
        /// <returns>Расшифрованный текст</returns>
        public string Decrypt(string strEntryText, int KeySize, string strPrivateKey)
        {
            using (var rsa = new RSACryptoServiceProvider(KeySize))
            {
                rsa.FromXmlString(strPrivateKey);

                byte[] byteEntry = Convert.FromBase64String(strEntryText);
                byte[] byteText = rsa.Decrypt(byteEntry, false);

                return Encoding.UTF8.GetString(byteText);
            }
        }

        /// <summary>
        ///  Метод для генерации приватного и закрытого ключа RSA
        /// </summary>
        /// <param name="KeySize">Размер ключа RSA</param>
        /// <returns></returns>
        public Dictionary<string, string> GetKey(int KeySize)
        {
            var dictKey = new Dictionary<string, string>();
            using (var rsa = new RSACryptoServiceProvider(KeySize))
            {
                dictKey.Add("PublicKey", rsa.ToXmlString(false));
                dictKey.Add("PrivateKey", rsa.ToXmlString(true));
            }
            return dictKey;
        }
    }
}
Использовать можно так:
C#:
namespace OldLockerTestEncTools
{
    using System;
    using System.Collections.Generic;

    internal static class Program
    {
        [STAThread]
        public static void Main()
        {
            string encryptedText = "r3xq1";
            Console.Title = "RSA 2048 string Encryption/Decryption";

            const int KEY_SIZE = 2048;
            EncTools.RSATool myRSA = new EncTools.RSATool();
            Dictionary<string, string> dictK = myRSA.GetKey(KEY_SIZE);

            Console.WriteLine($"Оригинальный текст: {encryptedText}");
            string Encrypt = myRSA.Encrypt(encryptedText, KEY_SIZE, dictK["PublicKey"]);
            Console.WriteLine($"Зашифрованный текст: {Encrypt}");

            string Decrypt = myRSA.Decrypt(Encrypt, KEY_SIZE, dictK["PrivateKey"]);
            Console.WriteLine($"Расшифрованный текст: {Decrypt}");
            Console.Read();
        }
    }
}
Использование с сохранение в файл и чтение из файла:
C#:
namespace OldLockerTestEncTools
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    internal static class Program
    {
        private static readonly string CurrDir = Environment.CurrentDirectory;

        [STAThread]
        public static void Main()
        {
            string encryptedText = "r3xq1";
            Console.Title = "RSA 2048 string Encryption/Decryption";

            // Размер ключа для шифрования/расшифровки
            const int KEY_SIZE = 2048;

            EncTools.RSATool myRSA = new EncTools.RSATool();

            // Получения ключей по размеру основного ключа
            Dictionary<string, string> dictK = myRSA.GetKey(KEY_SIZE);

            // Путь к файлу для публичного ключа
            string Publickey = Path.Combine(CurrDir, "publickey.key");

            // Путь к файлу для приватного ключа
            string Privatekey = Path.Combine(CurrDir, "PrivateKey.key");

            // Сохранение ключей в разные файлы
            File.WriteAllText(Publickey, dictK["PublicKey"]);
            File.WriteAllText(Privatekey, dictK["PrivateKey"]);

            Console.WriteLine($"Оригинальный текст: {encryptedText}");

            // Чтение ключей из файлов
            string encryptread = File.ReadAllText(Publickey);
            string decryptread = File.ReadAllText(Privatekey);

            // Шифрование текста
            string Encrypt = myRSA.Encrypt(encryptedText, KEY_SIZE, encryptread);
            Console.WriteLine($"Зашифрованный текст: {Encrypt}");

            // Расшифровка текста
            string Decrypt = myRSA.Decrypt(Encrypt, KEY_SIZE, decryptread);
            Console.WriteLine($"Расшифрованный текст: {Decrypt}");

            Console.Read();
        }
    }
}
Вот и всё!)
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Ну RSA не для этого создавалось. Во-первых, это очень медленно. Вот прям очень медленно. Во-вторых, размер строки, которую можно так зашифровать ограничивается размером ключа. Может дотнет фреймворк автоматически тебе разобьет данные строки на блоки, если они длинее ключа, но не факт, это нужно проверять. В-третьих, 1024 и 2048 в 2021 году слишком маленький размер ключа, чтобы считать такое RSA шифрования стойким. И в-четвертых, как это должно работать по хорошему: два клиента обмениваются публичными ключами RSA, с их помощью обмениваются сеансовыми ключами AES, гоняют между собой данные зашифрованные на сеансовых ключах и подписанные на своих приватных ключах RSA. И все, больше ничего не надо, эту схему никто не вскроет. Только нужно выбрать нормальную длину ключа RSA (4096 и выше) и нормальный режим для AES (CBC например).
 
Ну RSA не для этого создавалось. Во-первых, это очень медленно. Вот прям очень медленно. Во-вторых, размер строки, которую можно так зашифровать ограничивается размером ключа. Может дотнет фреймворк автоматически тебе разобьет данные строки на блоки, если они длинее ключа, но не факт, это нужно проверять. В-третьих, 1024 и 2048 в 2021 году слишком маленький размер ключа, чтобы считать такое RSA шифрования стойким. И в-четвертых, как это должно работать по хорошему: два клиента обмениваются публичными ключами RSA, с их помощью обмениваются сеансовыми ключами AES, гоняют между собой данные зашифрованные на сеансовых ключах и подписанные на своих приватных ключах RSA. И все, больше ничего не надо, эту схему никто не вскроет. Только нужно выбрать нормальную длину ключа RSA (4096 и выше) и нормальный режим для AES (CBC например).
Доброго времени, где об этом можно почитать подробнее? А лучше примеры в каких либо опен сурс проектах
 
Поддержу пост X-troll, единственное что удивляет, что уже 2048 не считается безопасным, если мне не изменяет память скомпрометированы только ключи длинной до 800. По крайней мере официально.
Автору: Имхо лучше использовать AES, есть открытые либы для .net. Github в помощь.
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх