Защита ключей шифрования в С#

Мне известно множество поставщиков криптографии, которые доступны в .NET Framework, а также основы их использования. Это достаточно просто.

Но я беспокоюсь об этом.

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

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

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

EDIT: Итак, если я правильно понимаю оба ответа ниже. Это означает, что, по сути, любая реализация (для обеспечения безопасности) требует, чтобы она была только для чтения или записи, но никогда не была одинаковой? Правильно ли это?

Ответ 1

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

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

Теперь, если вы все еще хотите спуститься по этому пути и хранить конфиденциальные данные без аутентификации, ваш лучший выбор - или, по крайней мере, простой способ, который находится на полпути, - это, вероятно, DPAPI (см. ProtectedData класс в System.Security.Cryptography). Он будет шифровать данные либо с помощью машинного ключа, либо с помощью ключа учетной записи пользователя (вы можете выбрать это). Так что программа, запущенная на другой машине или с другой учетной записью пользователя, не может получить к ней доступ. Windows попытается защитить эти ключи, но на самом деле любое приложение, работающее на соответствующей машине или с соответствующей учетной записью пользователя, сможет получить доступ к вашим данным.

Ответ 2

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

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

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

Ответ 3

Существуют различные возможные решения. Один из них использует RSA. В качестве альтернативы вы можете использовать тот же подход, что и в TLS.

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