Как использовать шифрование Rijndael с библиотекой классов .Net Core? (Не .NET Framework)
Как мы используем шифрование Rijndael в библиотеке классов .Net Core? (Не библиотека классов .Net Framework) Нам нужно создать общую библиотеку .Net Core для использования в нескольких проектах и реализовать методы шифрования и дешифрования, которые используют одно и то же шифрование Rijndael для всех проектов.
В настоящее время мы используем:
- VS Enterprise 2015
- С#
- .Net Core Class Library
- Ссылка .NETStandard, Version = v1.6
Похоже, что реализация Rijndael и AES отсутствует в выпуске .Net Core 1.0... похоже, только включает базовые классы. Как мы можем получить .NET-версию Rijndael или AES-шифрования, добавленную в качестве ссылки на новый проект библиотеки .NET Core Class?
Вот метод шифрования, который работает в .NET Framework 4.5.2:
public static string Encrypt(string valueToEncrypt, string symmetricKey, string initializationVector)
{
string returnValue = valueToEncrypt;
var aes = new System.Security.Cryptography.RijndaelManaged();
try
{
aes.Key = ASCIIEncoding.ASCII.GetBytes(symmetricKey);
aes.IV = ASCIIEncoding.ASCII.GetBytes(initializationVector);
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.ISO10126;
var desEncrypter = aes.CreateEncryptor();
var buffer = ASCIIEncoding.ASCII.GetBytes(valueToEncrypt);
returnValue = Convert.ToBase64String(desEncrypter.TransformFinalBlock(buffer, 0, buffer.Length));
}
catch (Exception)
{
returnValue = string.Empty;
}
return returnValue;
}
Ответы
Ответ 1
Разница (в .NET) между Rijndael и AES заключается в том, что Rijndael позволяет изменять размер блока, но AES этого не делает. Поскольку размер блока RijndaelManaged по умолчанию совпадает с размером блока AES (128 бит /16 байт), вы фактически используете AES.
Вместо создания экземпляра типа реализации по имени просто используйте factory (Aes.Create()
). Это работает как в .NET Core, так и в .NET Framework.
Другие вещи, о которых стоит упомянуть:
- Все экземпляры SymmetricAlgorithm являются IDisposable, вы должны использовать их в инструкции
using
.
- Все экземпляры ICryptoTransform (например, неверно названные
desEncryptor
) являются IDisposable, вы должны использовать их в инструкции using
.
- Отступ по ISO10126 недоступен в .NET Core 1.0. Если вам нужно быть совместимым с существующими потоками, вы можете применить дополнение и указать PaddingMode.None. В противном случае PKCS7 является более стандартным.
- Ваш ключ AES не очень случайный, поскольку он исходит из строки ASCII (много значений не будут действительными).
- Base64 по крайней мере имеет полный диапазон значений
- PBKDF2 (функция деривации ключа на основе пароля 2) с помощью класса Rfc2898DeriveBytes допускает разделяемую секвенцию, предсказуемый шум.
- KeyAgreement в целом лучше, но ни ECDH, ни классический DH не доступны в .NET Core 1.0.
- Обычно шифр должен вычислять случайный IV (вызов
aes.GenerateIV()
при использовании одного и того же объекта для нескольких операций) и представить его зашифрованным текстом. Таким образом, шифрование принимает ключ и открытый текст и создает шифрованный текст и IV. Decrypt принимает (ключ, IV, зашифрованный текст) и создает открытый текст.
Ответ 2
Если вы просто хотите зашифровать/дешифровать материал, не используйте Rijndael напрямую, так как ядро asp.net имеет гораздо более приятные оболочки, которые намного проще в использовании и, скорее всего, будут правильно защищены по умолчанию. Он известен как DataProtection.
using Microsoft.AspNetCore.DataProtection;
// During startup add DP
serviceCollection.AddDataProtection();
...
// the 'provider' parameter is provided by DI
public MyClass(IDataProtectionProvider provider)
{
_protector = provider.CreateProtector("Contoso.MyClass.v1");
}
...
// protect the payload
string protectedPayload = _protector.Protect(input);
Console.WriteLine($"Protect returned: {protectedPayload}");
...
// unprotect the payload
string unprotectedPayload = _protector.Unprotect(protectedPayload);
Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
Подробнее см. документы для защиты данных.