Использование контейнеров ключей RSA в качестве генератора ключей для AES - могу ли я сделать это лучше? - PullRequest
0 голосов
/ 19 января 2019

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

Я хотел использовать AES (без реальной причины, просто показалось, что это хороший вариант), поэтому я начал изучать, как создавать и хранить защищенные ключи для AES. Я не мог найти много способов реализации, просто много чего не делать. Единственный достойный способ, который я нашел, - это использование .NET Key Containers (https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-store-asymmetric-keys-in-a-key-container), но он предназначен для асимметричных ключей.

Итак, я начал играть с ним, и ниже приведен рабочий пример использования RSA в сочетании с AES:

    public static byte[] Encrypt(byte[] data, byte[] salt)
    {
        byte[] encrypted;
        Rfc2898DeriveBytes deriveBytes;

        // Sanity
        if (data == null || data.Length <= 0)
            throw new ArgumentNullException("data");
        if (salt == null || salt.Length <= 0)
            throw new ArgumentNullException("salt");

        // Create AES object
        using (Aes aes = Aes.Create())
        {
            deriveBytes = new Rfc2898DeriveBytes(GetKeyFromContainer(), salt, MAX_ITERATIONS);
            aes.Key = deriveBytes.GetBytes(32);
            aes.IV = salt;

            ICryptoTransform cryptoTransform = aes.CreateEncryptor(aes.Key, aes.IV);
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(data, 0, data.Length);
                }
                encrypted = memoryStream.ToArray();
            }
        }

        return encrypted;
    }


    public static byte[] Decrypt(byte[] data, byte[] salt)
    {
        byte[] decrypted;
        Rfc2898DeriveBytes deriveBytes;

        // Sanity
        if (data == null || data.Length <= 0)
            throw new ArgumentNullException("data");
        if (salt == null || salt.Length <= 0)
            throw new ArgumentNullException("salt");

        // Create AES object
        using (Aes aes = Aes.Create())
        {
            deriveBytes = new Rfc2898DeriveBytes(GetKeyFromContainer(), salt, MAX_ITERATIONS);
            aes.Key = deriveBytes.GetBytes(32);
            aes.IV = salt;

            ICryptoTransform cryptoTransform = aes.CreateDecryptor(aes.Key, aes.IV);
            using (MemoryStream memoryStream = new MemoryStream(data))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read))
                {
                    using (StreamReader streamReader = new StreamReader(cryptoStream))
                    {
                        decrypted = Encoding.Default.GetBytes(streamReader.ReadToEnd());
                    }
                }
            }
        }

        return decrypted;
    }

    private static byte[] GetKeyFromContainer()
    {
        CspParameters parameters;
        RSACryptoServiceProvider rsaServiceProvider;

        parameters = new CspParameters();
        parameters.KeyContainerName = KEY_CONTAINER_NAME;

        rsaServiceProvider = new RSACryptoServiceProvider(parameters);

        return Encoding.Default.GetBytes(rsaServiceProvider.ToXmlString(true));
    }

Итак, к вопросам:

  1. Насколько плохо использовать RSA для генерации асимметричного ключа, который затем будет использоваться AES? Каковы недостатки, если таковые имеются, к этой стратегии?
  2. Есть ли лучший метод / алгоритм для шифрования / дешифрования импортированных документов (не AES)?

Я немного неопытен, когда дело доходит до криптографии, поэтому любая помощь или учебные материалы очень ценятся.

...