LicenseProvider в .NET, использующий шифрование RSA для защиты лицензии продукта - PullRequest
3 голосов
/ 14 декабря 2009

Я пытаюсь найти надежную схему лицензирования, используя Microsoft LicenseProvider. Моя мысль состоит в том, чтобы использовать асинхронное шифрование с помощью RSA (RSACryptoServiceProvider с 2048-битными ключами). Я обнаружил, что это довольно легко, но я не уверен, насколько надежен механизм на самом деле. Это не для развлечения и требует защиты от копирования ряда продуктов (мы говорим ~ 100 установок) в США. Срок годности не требуется.

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

(Кстати, идентификатор компьютера представляет собой комбинацию: MAC-адрес + серийный номер процессора + последовательный жесткий диск. Поэтому, если одно из этих изменений изменится, потребуется продление лицензии)

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

Теперь, кроме покупки дорогостоящего решения стороннего производителя, взлома и обхода лицензионной DLL, насколько безопасна эта идея использования RSA + computerID?

(Да, мы пытаемся запутать код, чтобы сделать его лучше)

Спасибо за отзыв!

Ответы [ 3 ]

3 голосов
/ 16 января 2013

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

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

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

Далее, «лицензия», которая шифрует лицензию, будет просто хеширована или симметрично зашифрована с помощью «уникального идентификатора» компьютера, который предоставляется серверу через некоторое время во время обработки платежа. Таким образом, только тот компьютер может генерировать правильную «парольную фразу», если хотите, которая может восстановить ключ для расшифровки ключа для дешифрования программы / dll / whathaveyou.

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

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

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

1 голос
/ 07 июля 2010

Просто для пояснения (что вы, возможно, имели в виду), вы должны подписать данные, используя [provider] .SignData ([params]) и для проверки лицензии используйте [provider] .VerifyData ([params]). Также не забудьте удалить закрытый ключ из пары ключей, которую вы создали.

1 голос
/ 02 июля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...