- •А.А. Волосевич
- •2. Базовые технологии платформы .Net 5
- •2. Базовые технологии платформы .Net 4
- •2. Базовые технологии платформы .Net
- •2.1. Работа с Числами
- •2.2. Дата и время
- •2.3. Работа со строками и текстом
- •2.4. Преобразование информации
- •2.5. Отношения равенства и порядка
- •Сравнение для выяснения равенства
- •Сравнение для выяснения порядка
- •2.6. Жизненный цикл объектов
- •Алгоритм «сборки мусора»
- •Финализаторы и интерфейс iDisposable
- •2.7. Перечислители и итераторы
- •2.8. Интерфейсы стандартных коллекций
- •2.9. Массивы и класс system.Array
- •2.10. Типы для работы с коллекциями-списками
- •2.11. Типы для работы с коллекциями-множествами
- •2.12. Типы для работы с коллекциями-словарями
- •2.13. Типы для создания пользовательских коллекций
- •2.14. Технология linq to objects
- •1. Оператор условия Where().
- •2. Операторы проекций.
- •3. Операторы упорядочивания.
- •4. Оператор группировки GroupBy().
- •5. Операторы соединения.
- •6. Операторы работы с множествами.
- •7. Операторы агрегирования.
- •8. Операторы генерирования.
- •9. Операторы кванторов и сравнения.
- •10. Операторы разбиения.
- •11. Операторы элемента.
- •12. Операторы преобразования.
- •2.15. Работа с объектами файЛовой системы
- •2.16. Ввод и вывод информации
- •Потоки данных и декораторы потоков
- •2. Классы для работы с потоками, связанными с хранилищами.
- •3. Декораторы потоков.
- •4. Адаптеры потоков.
- •Адаптеры потоков
- •2.17. Основы xml
- •2.18. Технология linq to xml
- •Создание, сохранение, загрузка xml
- •Запросы, модификация и трансформация xml
- •Пространства имен xml
- •2.19. ДОполнительные возможности обработки xml
- •2.20. Сериализация
- •Сериализация времени выполнения
- •Сериализация контрактов данных
- •2.21. Состав и взаимодействие сборок
- •2.22. Метаданные и получение информации о типах
- •2.23. Позднее связывание и кодогенерация
- •2.24. Динамические типы
- •2.25. Атрибуты
- •2.26. Файлы конфигуРации
- •2.27. Основы мНогопоточноГо программирования
- •2.28. Синхронизация потоков
- •2.29. Библиотека параллельных расширений
- •Параллелизм на уровне задач
- •Параллелизм при императивной обработке данных
- •Параллелизм при декларативной обработке данных
- •Обработка исключений и отмена выполнения задач
- •Коллекции, поддерживающие параллелизм
- •2.30. Асинхронный вызов методов
- •2.31. Процессы и домены
- •2.32. Безопасность
- •Разрешения на доступ
- •Изолированные хранилища
- •Криптография
- •2.33. Диагностика
Криптография
Криптографические возможности .NET применяются для защиты данных. Один из простейших способов использования криптографии – методы Encrypt() и Decrypt() классов File и FileInfo. Первый метод выполняет прозрачное шифрование файла, используя ключ, сгенерированный по паролю текущего пользователя. «Прозрачным» этот вид шифрования назван потому, что его эффект будет заметен только для других пользователей (а не для того, который его выполнил). Второй метод устраняет прозрачное шифрование файла.
File.WriteAllText("myfile.txt", "This is a sample text");
File.Encrypt("myfile.txt");
Ключ, созданный по паролю текущего пользователя, могут применять для шифрования данных и статические методы Protect() и Unprotect() класса ProtectedData (пространство имён System.Security.Cryptography в сборке System.Security.dll). Первый параметр этих методов – массив байт, подлежащих шифровке/дешифровке. Второй параметр – массив байт, дополнительно добавляемый к ключу для усиления его защиты. Третий параметр – элемент перечисления DataProtectionScope, указывающий на методику выработки ключа (текущий пользователь или текущий компьютер).
// шифруемые данные
byte[] data = Encoding.UTF8.GetBytes("secret");
// не используем усиление ключа, созданного по паролю пользователя
byte[] en_1 = ProtectedData.Protect(data, null,
DataProtectionScope.CurrentUser);
// используем усиление ключа, созданного по данным текущей машины
byte[] en_2 = ProtectedData.Protect(data, new byte[] { 2, 2, 5 },
DataProtectionScope.LocalMachine);
Одним из методов защиты информации является хеширование. Это односторонне шифрование, вырабатывающее по массиву данных короткий фиксированный набор байт – хэш. Хэш является своеобразной «подписью» для данных, так как любое изменение данных ведет к изменению хэша. Чем длиннее хэш, тем более стойким он является (т.е. тем труднее найти два разных массива данных с одинаковым хэшем).
Для хеширования следует использовать один из классов, наследников класса HashAlgorithm. Например, в следующем фрагменте кода демонстрируется хеширование по алгоритму SHA-256 (http://ru.wikipedia.org/wiki/SHA-2).
byte[] data = Encoding.UTF8.GetBytes("password");
byte[] hash = SHA256.Create().ComputeHash(data);
Метод ComputeHash() может принимать в качестве аргумента не только массив байт, но и поток данных.
Симметричное шифрование использует для зашифровки и расшифровки информации один и тот же ключ. Платформа .NET содержит реализацию четырёх симметричных алгоритмов, лучший из которых – алгоритм Rijndael (http://ru.wikipedia.org/wiki/Rijndael). Реализации алгоритмов оформлены как наследники абстрактного класса SymmetricAlgorithm. Для работы симметричным алгоритмам требуется байтовый ключ установленной длины и вектор инициализации (это также байтовый массив). Далее представлен пример симметричного шифрования последовательности байтов, по мере того как она записывается в файл.
// ключ и вектор инициализации должны быть 126, 128 или 256 бит
byte[] key = Encoding.UTF8.GetBytes("-My private key-");
byte[] iv = Encoding.UTF8.GetBytes("--Init vector--");
byte[] data = Encoding.UTF8.GetBytes("Secret message");
SymmetricAlgorithm algorithm = Rijndael.Create();
ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv);
using (var stream = File.Create("data.bin"))
{
using (var cryptoStream = new CryptoStream(stream, encryptor,
CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
}
}
Предыдущий пример демонстрирует использование декоратора CryptoStream для организации зашифрованного потока. Этот декоратор можно комбинировать с другими классами, например DeflateStream (сжатый поток).
Кроме симметричного шифрования платформа .NET предоставляет реализацию двух алгоритмов шифрования с открытым ключом – DSA и RSA. Второй алгоритм является более стойким. Мы не будем подробно останавливаться на нюансах использования RSA1, приведём лишь фрагмент кода, который иллюстрирует этот вид шифрования.
byte[] data = Encoding.UTF8.GetBytes("Secret message");
using(var rsa = new RSACryptoServiceProvider())
{
byte[] encrypted = rsa.Encrypt(data, true);
}