Мне было поручено создать внутреннюю систему документооборота на моем рабочем месте. Требование задачи состоит в том, чтобы зашифровать импортированные в систему документы и расшифровать их только по запросу конечного пользователя. Кроме того, конечный пользователь не будет знать пароль / ключ для расшифровки, система должна полностью обрабатывать шифрование и дешифрование самостоятельно.
Я хотел использовать 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));
}
Итак, к вопросам:
- Насколько плохо использовать RSA для генерации асимметричного ключа, который затем будет использоваться AES? Каковы недостатки, если таковые имеются, к этой стратегии?
- Есть ли лучший метод / алгоритм для шифрования / дешифрования импортированных документов (не AES)?
Я немного неопытен, когда дело доходит до криптографии, поэтому любая помощь или учебные материалы очень ценятся.