Подтвердить что ты не робот

Каков наилучший способ защиты конфиденциальных данных в коде?

Я изучал способы защиты моего кода от декомпиляции.

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

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

В ASP.NET есть возможность переместить конфиденциальные данные в файл .config и зашифровать его, но для этого требуется ключ сервера, т.е. связанный с одним компьютером. Я не много читал об этом, но я полагаю, что что-то подобное доступно для настольных приложений. Но мне нужно это для работы на любом компьютере, на котором установлено приложение.

И вот вопрос: существуют ли способы кодирования/защиты таких данных, чтобы их нельзя было читать вместе с декомпилированным кодом?

4b9b3361

Ответ 1

Первый совет - никогда не хранить ничего чувствительного в вашем коде напрямую. Вы всегда можете изменить это, независимо от того, насколько умно вы пытаетесь запутать его.

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

Если я правильно интерпретирую ваш сценарий, то у вас есть код, который должен быть развернут в некоторых помещениях клиента, а ваш код подключен к базе данных (которая, я полагаю, также находится под наблюдением клиента), для подключения к ней требуется пароль, Этот пароль известен этому клиенту, поэтому попытка скрыть его от клиента бесполезна. Вы хотите ограничить доступ к этому паролю от любого, кто не должен его знать.

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

Кроме того, шифрование отдельного файла оказывается проблемой - если вы это сделаете, тогда будет задействован ключ, который снова должен быть каким-то образом обеспечен - бесконечная рекурсия на этом пути:) Обеспечение доступа к файлу часто бывает достаточно, но если вам действительно нужно быть как можно более безопасным, тогда решение должно использовать шифрование на основе паролей для файла. Но идея здесь заключается не в том, чтобы хранить пароль в другом месте в системе, а скорее как внеполосная информация (например, в физическом хранилище) и ввод пароля при запуске приложения. У этого тоже есть свои проблемы: физическое присутствие человека требуется для (повторного) запуска приложения, и вы все равно можете получить пароль из ОЗУ компьютера, на котором работает приложение. Но это, вероятно, лучшее, что вы можете сделать без специального оборудования.

Еще одна хорошая альтернатива шифрованию на основе паролей - это полагаться на "хранилища паролей" для ОС, такие как Windows Изолированное хранилище, выключить между не шифрование вообще и сохранение пароля вне диапазона.

Ответ 2

Это не ответ на шифрование, но один из способов обеспечить его безопасность - это сделать все вызовы базы данных через веб-службу. Тогда ваши учетные данные подключения будут сохранены на вашем защищенном сервере, и клиенты будут проходить через все вызовы.

Ничего секретного не хранится в вашем повторном распространении вообще...

Ответ 3

Я столкнулся с этой проблемой в прошлом и придумал три способа решения этой проблемы, но я не уверен, что любой из них идеален:

  • Обфускать или зашифровать значение и надеяться на лучшее. Шифрование, конечно же, является просто дополнительным уровнем обфускации, поскольку ключ должен быть доставлен вместе с остальными.
  • Устранить необходимость в самом ключе, используя вместо этого одностороннее шифрование. Для создания открытого ключа используйте закрытый ключ. Это можно использовать для лицензирования или проверки пароля. Вы генерируете лицензии с помощью закрытого ключа, но открытый ключ может использоваться для их проверки. Или вы используете закрытый ключ для генерации пароля, который может быть проверен, но не отменен с помощью открытого ключа.
  • Создайте собственный системный механизм генерации ключей, аналогичный используемому ASP.NET. Вы можете ограничить эффект, который кто-то может изменить на шифрование/обфускацию на шаге 1, создав уникальный ключ для каждой установки или сайта.

Ответ 4

Существует множество методов, но реальность такова, что если вы действительно хотите защитить свой код, единственное решение - использовать "профессиональные" продукты:-) не пытайтесь изобретать колесо. Обычно эти продукты имеют опции для шифрования строк. Реальная проблема другая: без профессионального продукта (и даже с профессиональным продуктом) эксперт может просто поставить точку останова и посмотреть параметры, переданные библиотечному методу (например, тот, который открывает соединения). Теперь... Если вы действительно хотите зашифровать строки вашего кода, это довольно просто. Но было бы полезно? Нет.

Теперь, так, чтобы никто не отметил это как "не ответ", я отправлю некоторый простой код шифрования/дешифрования:

// Generate key. You do it once and save the key in the code
var encryptorForGenerateKey = Aes.Create();
encryptorForGenerateKey.BlockSize = 128;
encryptorForGenerateKey.KeySize = 128;
encryptorForGenerateKey.GenerateKey();
encryptorForGenerateKey.GenerateIV();

var key = encryptorForGenerateKey.Key;
var iv = encryptorForGenerateKey.IV;

// Encrypt: this code doesn't need to be in the program. You create a console
// program to do it
var encryptor = Aes.Create();
var encryptorTransformer = encryptorForGenerateKey.CreateEncryptor(key, iv);

string str = "Hello world";
var bytes = Encoding.UTF8.GetBytes(str);
var encrypted = encryptorTransformer.TransformFinalBlock(bytes, 0, bytes.Length);
var encryptedString = Convert.ToBase64String(encrypted);

Console.WriteLine(encryptedString);

// Decrypt: this code needs to be in the program

var decryptor = Aes.Create();
var decryptorTransformer = decryptor.CreateDecryptor(key, iv);

byte[] encrypted2 = Convert.FromBase64String(encryptedString)

var result = decryptorTransformer.TransformFinalBlock(encrypted2, 0, encrypted2.Length);

var str2 = Encoding.UTF8.GetString(result);

Этот код явно не защищен. Любой может декомпилировать программу, добавить Console.WriteLine(str2) и перекомпилировать ее.

Ответ 5

Вы можете, конечно, зашифровать строку перед ее компиляцией, но ваш код понадобится в обычном тексте когда-нибудь, если вы используете простой db или http url.

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

Вы можете, например, поместить COM или С++ dll для хранения зашифрованных строк. Неуправляемая dll не является декомпиляционной, однако экспертные люди могут, конечно, понять разборку dll. И, как говорилось ранее, иногда вам понадобятся простые данные, и в этот момент нет защиты, которая может продолжаться.

Единственное, что вы можете сделать, это изменить свою архитектуру.

Например, если ваш db находится в сети, а ваше приложение - клиентское приложение, вы можете подключиться к веб-службам. Затем вы можете выставлять только те веб-сервисы, которые пользователю действительно нужно использовать, и нет никаких проблем с написанием запросов sql-пользователей. Затем вы можете добавить логику защиты на сервере, а не на клиент.

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

Ответ 6

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

О хранении учетных данных, моя обычная практика заключается в том, чтобы всегда хранить их в файле конфигурации приложения. Если тогда мне нужно его защитить, я использую SecureString и некоторое шифрование. И это может работать для любой информации конфигурации, а не только для учетных данных. Существует хорошая статья об обеспечении файлов конфигурации здесь: Шифрование паролей в файле .NET app.config

Ответ 7

Возможно, вам стоит прочитать еще кое-что о шифровании web.config http://learn.iis.net/page.aspx/141/using-encryption-to-protect-passwords/

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