Как использовать переменные с файла .config?

в самом файле .config я внес ключ и IV, чтобы выполнить шифр AES

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="EncryptionKey" value="your-32-char-long-encryption-key-here1234" />
    <add key="IV" value="your-16-char-IV-here" />
  </appSettings>
</configuration>

и как мне использовать EncryptionKey и IV чтобы выполнить AES шифр: вот код класса который выполняет сначала шифр параметров и ключей по AES, после выполняет экспорт в БД:

public class ElGamalParametersExporter
{
private string connectionString;
private static readonly byte[] Key = Encoding.UTF8.GetBytes("your-32-char-long-encryption-key-here1234"); // 32 bytes for AES-256
private static readonly byte[] IV = Encoding.UTF8.GetBytes("your-16-char-IV-here"); // 16 bytes for AES

public ElGamalParametersExporter(string dbFileName)
{
    string relativePathToDB = Path.Combine("database", dbFileName);
    string absolutePathToDB = Path.GetFullPath(relativePathToDB);
    connectionString = "Data Source=" + absolutePathToDB + ";Version=3;";
}

private static byte[] EnsureCorrectLength(byte[] input, int length)
{
    if (input.Length == length)
        return input;

    byte[] output = new byte[length];
    if (input.Length > length)
    {
        Array.Copy(input, output, length);
    }
    else
    {
        Array.Copy(input, output, input.Length);
        for (int i = input.Length; i < length; i++)
        {
            output[i] = 0x00; // Zero padding for shorter inputs
        }
    }
    return output;
}

private static string Encrypt(string plainText)
{
    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Key = EnsureCorrectLength(Key, 32);
        aesAlg.IV = EnsureCorrectLength(IV, 16);

        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        using (var msEncrypt = new MemoryStream())
        {
            using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (var swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(plainText);
                }
            }
            return Convert.ToBase64String(msEncrypt.ToArray());
        }
    }
}

я не понимаю как можно сделать так, я пытался но ничего не вышло:

using System.Configuration;

public class ElGamalParametersExporter
{
private string connectionString;
private byte[] key;
private byte[] iv;

public ElGamalParametersExporter(string dbFileName)
{
    // Load key and IV from configuration file
    LoadEncryptionSettings();

    // Your existing code
    string relativePathToDB = Path.Combine("database", dbFileName);
    string absolutePathToDB = Path.GetFullPath(relativePathToDB);
    connectionString = "Data Source=" + absolutePathToDB + ";Version=3;";
}

private void LoadEncryptionSettings()
{
    // Read key and IV from configuration file
    string encryptionKey = ConfigurationManager.AppSettings["EncryptionKey"];
    string initializationVector = ConfigurationManager.AppSettings["IV"];

    // Convert key and IV from Base64 string to byte arrays
    key = Convert.FromBase64String(encryptionKey);
    iv = Convert.FromBase64String(initializationVector);
}
private string Encrypt(string plainText)
{
using (Aes aesAlg = Aes.Create())
{
    aesAlg.Key = EnsureCorrectLength(key, 32);
    aesAlg.IV = EnsureCorrectLength(iv, 16);

    ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

    using (var msEncrypt = new MemoryStream())
    {
        using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        {
            using (var swEncrypt = new StreamWriter(csEncrypt))
            {
                swEncrypt.Write(plainText);
            }
        }
        return Convert.ToBase64String(msEncrypt.ToArray());
    }
}
}

здесь старый код рабочий и новый не рабочий, якобы он пишет что там пусто и ничего нету


Ответы (1 шт):

Автор решения: aepot

В связи с появлением новых сведений о том что используется старый фреймворк, а так же непониманием того что я ответил ранее, пиреписываю ответ полностью.

Почему ключ не читается из .config файла я без понятия, так как в вопросе нет данных о типе приложения и о том, как вы этот конфиг к нему подключаете. Поэтому покажу как просто записать ключ в текстовый файл. Если это Windows Forms, то вам стоит наверное почитать документацию.

Вот вам полный арсенал методов

private static byte[] GenerateNewKey()
{
    RandomNumberGenerator rng = RandomNumberGenerator.Create();
    byte[] key = new byte[32];
    rng.GetBytes(key);
    return key;
}

private static void SaveKey(byte[] key, string path)
{
    string base64 = Convert.ToBase64String(key);
    File.WriteAllText(path, base64);
}

private static byte[] LoadKey(string path)
{
    string base64 = File.ReadAllText(path);
    return Convert.FromBase64String(base64);
}

private static string Encrypt(string text, byte[] key)
{
    using (Aes aes = Aes.Create())
    {
        aes.Key = key;
        using (MemoryStream ms = new MemoryStream())
        {
            ms.Write(aes.IV, 0, aes.IV.Length);
            using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true))
            {
                byte[] data = Encoding.UTF8.GetBytes(text);
                cs.Write(data, 0, data.Length);
            }
            return Convert.ToBase64String(ms.ToArray());
        }
    }
}

private static string Decrypt(string base64, byte[] key)
{
    using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64)))
    using (Aes aes = Aes.Create())
    {
        byte[] iv = new byte[aes.BlockSize / 8];
        ms.Read(iv, 0, iv.Length);
        aes.Key = key;
        aes.IV = iv;
        using (MemoryStream output = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true))
            {
                cs.CopyTo(output);
            }
            return Encoding.UTF8.GetString(output.ToArray());
        }
    }
}
  • GenerateNewKey - создаёт новый случайный ключ
  • SaveKey - сохраняет ключ в файл в формате Base64
  • LoadKey - грузит ключ из файла, в который он ранее был сохранён с помощью SaveKey
  • Encrypt - шифрует данные с помощью ключа и возвращают строку шифра в формате Base64
  • Decyprt - расшифровывает Base64 строку с помощью ключа и возвращает расшифрованный текст

Как видно, здесь IV хранить не надо, он при шифровании записывается прямо в данные.

Пример, как создать новый ключ и записать в файл

string dir = AppDomain.CurrentDomain.BaseDirectory;
string fileName = "key.txt";
string path = Path.Combine(dir, fileName);
byte[] key = GenerateNewKey();
SaveKey(key, path);

Для этого можно создать пустой консольный проект или добавить функцию в своё приложение, которое если ключа не нашло, создаёт новый автоматически.

Вот что записалось в файл key.txt

KQtQ6u/6/hoqSlscydisTIazOHHaL5XBGJA9tLwZSbE=

Как прочитать ключ из файла

byte[] key = LoadKey(path);

Пример шифровки/расшифровки

string text = "Hello World";
string encrypted = Encrypt(text, key);
Console.WriteLine(encrypted);
string decrypted = Decrypt(encrypted, key);
Console.WriteLine(decrypted);

Вывод в консоль

EDj0AhvXJvul5eGlDmoc2SRk4NWLNEVr0BJImN/HrRI=
Hello World

Методы Encrypt и Decrypt, это переписанные под старый 4.8 фреймворк из ранее данного мной ответа: C# Шифрование строки со всегда разным результатом

→ Ссылка