{"id":14284,"url":"\/distributions\/14284\/click?bit=1&hash=82a231c769d1e10ea56c30ae286f090fbb4a445600cfa9e05037db7a74b1dda9","title":"\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0444\u0438\u043d\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u0430\u043d\u0446\u044b \u0441 \u0441\u043e\u0431\u0430\u043a\u0430\u043c\u0438","buttonText":"","imageUuid":""}

Шифрование данных на языке C#

Всем привет.

Я – технический специалист внутреннего аудита. В мои обязанности, помимо всего прочего, входит создание инструментов ETL. Чаще всего это консольные программы написанные на языке программирования C#, которые получают данные из различных источников (БД различных вендоров, файлы и т.д.), проводят при необходимости операции трансформации данных и загружают данные в хранилище. Так как программы активно подключаются к БД и при этом должны иметь права на запись и чтение — возникает проблема хранения данных учетных записей (логины и пароли), под которыми программа будет подключаться к БД. Навскидку находятся три решения. Рассмотрим их более подробно:

  1. Хранить данную критическую информацию «зашитой» в исполняемый файл exe. Из плюсов – относительная надёжность хранения, ведь для получения доступа к этой информации из вне потребуется дизассемблировать/декомпилировать исполняемый файл, из минусов — необходимость постоянно перекомпилировать исполняемый файл при смене пароля в учетных записях и опять же хранение этих данных в открытом виде в исходном коде программы, где эта информация и может быть считана посторонним наблюдателем.
  2. Хранить информацию в настроечных файлах приложения, но при этом само приложение должно работать на сервере приложений с ограниченным доступом. Из плюсов – легкая настройка в случае изменения данных учетных записей, из минусов – легкий доступ к критической информации всем, кто может зайти на сервер приложений.
  3. Хранить информацию в настроечных файлах программы в зашифрованном виде. Из плюсов – легкая настройка приложения в случае изменения данных, программа может работать не только на сервере приложений, критически важная информация хранится в виде недоступном для постороннего наблюдателя. Из минусов – только необходимость модернизации ранее написанного ПО.

По совокупности плюсов и минусов выбираем третий вариант.

Теперь чуть –чуть теории. Что же такое шифрование и для чего оно нужно? Шифрование –это трансформация для ее сокрытия от не авторизованных лиц,

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

Выделяем основные способы шифрования

  • симметричное
  • асимметричное
  • хеширование

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

Асимметричное шифрование это способ при котором создаются два математически связанных ключа, один из которых передается открытым (доступных для всех) способом, а второй, приватный ключ — для расшифровывания

Где используется шифрование? Например, практически во всех популярных мессенджерах сообщения пользователей шифруются таким образом, что прочитать их могут только отправитель и адресат, большинство соединений в глобальной сети интернет сейчас используют сетевой протокол HTTPS обеспечивающий шифрование передаваемых данных. Хеширование, несмотря на необратимость шифрования данных активно используется для проверки паролей в различных системах доступа, начиная от операционных систем и систем авторизации на различных сайтах и форумах.

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

В итоге мы реализовали следующую схему. В динамически подключаемой библиотеке (dll) был создан статический класс инкапсулировавший в себе весь функционал требуемый нам для шифрования/расшифровывания данных. Вот пример функции выполняющей шифрование:

static public object Encrypt(byte[] data, string password) { SymmetricAlgorithm sa = null; try { sa = Rijndael.Create(); ICryptoTransform ct = sa.CreateEncryptor( (new PasswordDeriveBytes(password, null)).GetBytes(16), new byte[16]); MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write); cs.Write(data, 0, data.Length); cs.FlushFinalBlock(); return ms.ToArray(); } catch (Exception e) { return e; } } static public string Encrypt(string data, string password) { object tmp = Encrypt(Encoding.UTF8.GetBytes(data), password); if (!(tmp is Exception)) { return Convert.ToBase64String((byte[])tmp); } else return null; }

Теперь при создании новых программ, где требуется хранить зашифрованную информацию мы просто подключаем созданную нами dll и просто вызываем требуемые нам функции и получаем информацию для передачи в БД:

public string UserLogin { get { object tmp = dll.Crypt.Decrypt(userLogin, getKey()); return tmp is Exception ? "" : tmp.ToString(); } } При этом, в настроечном XML файле хранится информация в следующем виде: <Settings> <userLogin>p+esX621QNMR09YyY4plJQ==</userLogin> <userPassword>og6kLzB2woGVlnO0ZRisDA==</userPassword> </Settings>

Таким образом мы скрываем от постороннего наблюдателя критически важную информацию. При необходимости, учитывая достаточно слабую защищённость от дизассемблирования/декомпиляции программ, созданных на платформе. Net можно дополнительно обфусцировать исполняемый файл программы с целью сокрытия механизма получения ключа.

0
3 комментария
Bulat Ziganshin

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

Ответить
Развернуть ветку
Шурик Никулин

Bulat Ziganshin, т.е. конечный пользователь, поставит себе студию, каким то образом подцепится к сервису,  получит исходники, и будет дебажить код? 

Ответить
Развернуть ветку
Василий

Доброго времени суток, а каков код для расшифровки  того, что получилось?

Ответить
Развернуть ветку
0 комментариев
Раскрывать всегда