Как создать и проверить лицензионный ключ программного обеспечения?
В настоящее время я занимаюсь разработкой продукта (разработанного на C#), который будет доступен для загрузки и установки бесплатно, но в очень ограниченной версии. Чтобы получить доступ ко всем функциям, пользователь должен оплатить лицензионный сбор и получить ключ. Затем этот ключ будет введен в приложение, чтобы "разблокировать" полную версию.
Поскольку использование лицензионного ключа вроде обычного, мне интересно:
- Как это обычно решается?
- Как я могу сгенерировать ключ и как он может быть проверен приложением?
- Как можно также избежать публикации ключа в Интернете и его использования другими лицами, которые не заплатили лицензию (ключ, который в основном не является "их").
Думаю, мне следует как-то привязать ключ к версии приложения, чтобы можно было взимать плату за новые ключи в версиях функций.
Что-нибудь еще, о чем я должен думать в этом сценарии?
17 ответов
Предостережение: вы не можете запретить пользователям пиратство, а только упрощают честным пользователям правильные действия.
Предполагая, что вы не хотите делать специальную сборку для каждого пользователя, тогда:
- Создайте себе секретный ключ для продукта
- Взять имя пользователя
- Объедините имя пользователя, секретный ключ и хеш с (например) SHA1
- Распакуйте хеш SHA1 в виде буквенно-цифровой строки. Это индивидуальный пользовательский "Ключ продукта"
- Внутри программы сделайте тот же хеш и сравните с ключом продукта. Если равно, хорошо.
Но, повторюсь: это не предотвратит пиратство
Я недавно читал, что этот подход не очень криптографически обоснован. Но это решение уже слабое (поскольку само программное обеспечение должно где-то включать секретный ключ), поэтому я не думаю, что это открытие делает решение недействительным настолько, насколько оно возможно.
Просто подумал, что я действительно должен упомянуть об этом, хотя; если вы планируете извлечь что-то еще из этого, будьте осторожны.
Существует много способов создания лицензионных ключей, но очень немногие из них действительно безопасны. И очень жаль, потому что для компаний лицензионные ключи имеют почти такую же ценность, как реальные деньги.
В идеале вы хотели бы, чтобы ваши лицензионные ключи имели следующие свойства:
Только ваша компания должна иметь возможность генерировать лицензионные ключи для ваших продуктов, даже если кто-то полностью обратный инжиниринг ваших продуктов (что произойдет, я говорю из опыта). Запутывать алгоритм или скрывать ключ шифрования в вашем программном обеспечении действительно невозможно, если вы серьезно относитесь к контролю лицензирования. Если ваш продукт успешен, кто-то сделает генератор ключей в течение нескольких дней с момента выпуска.
Лицензионный ключ должен использоваться только на одном компьютере (или, по крайней мере, вы должны быть в состоянии контролировать это очень жестко)
Лицензионный ключ должен быть коротким, его легко набирать или диктовать по телефону. Вы не хотите, чтобы каждый клиент звонил в службу технической поддержки, потому что он не понимает, содержит ли ключ "l" или "1". Ваш отдел поддержки поблагодарит вас за это, и у вас будет меньше затрат в этой области.
Итак, как вы решаете эти проблемы?
Ответ прост, но технически сложен: цифровые подписи с использованием криптографии с открытым ключом. Ваши лицензионные ключи должны быть подписаны "документами", содержащими некоторые полезные данные, подписанные закрытым ключом вашей компании. Подписи должны быть частью лицензионного ключа. Продукт должен проверить лицензионные ключи с соответствующим открытым ключом. Таким образом, даже если кто-то имеет полный доступ к логике вашего продукта, он не может генерировать лицензионные ключи, потому что у него нет закрытого ключа. Лицензионный ключ будет выглядеть следующим образом: BASE32(CONCAT(DATA, PRIVATE_KEY_ENCRYPTED(HASH(DATA))))) Самая большая проблема здесь заключается в том, что классические алгоритмы с открытым ключом имеют большие размеры подписи. RSA512 имеет 1024-битную подпись. Вы не хотите, чтобы ваши лицензионные ключи имели сотни символов. Одним из наиболее эффективных подходов является использование криптографии с эллиптическими кривыми (с осторожными реализациями, чтобы избежать существующих патентов). Ключи ECC примерно в 6 раз короче, чем ключи RSA, при той же прочности. Вы можете дополнительно уменьшить размеры подписи, используя такие алгоритмы, как алгоритм цифровой подписи Schnorr (срок действия патента истек в 2008 году - хорошо:))
Это достигается путем активации продукта (хороший пример - Windows). По сути, для клиента с действующим лицензионным ключом вам необходимо сгенерировать некоторые "данные активации", которые представляют собой подписанное сообщение, в которое в качестве подписанных данных входит идентификатор оборудования компьютера. Обычно это делается через Интернет, но только ОДИН РАЗ: продукт отправляет лицензионный ключ и идентификатор аппаратного обеспечения компьютера на сервер активации, а сервер активации отправляет обратно подписанное сообщение (которое также можно сделать коротким и легко диктовать через Телефон). С этого момента продукт проверяет не лицензионный ключ при запуске, а данные активации, для которых компьютер должен быть одинаковым для проверки (в противном случае данные будут отличаться, а цифровая подпись не будет проверяться). Обратите внимание, что проверка данных активации не требует проверки через Интернет: достаточно проверить цифровую подпись данных активации с помощью открытого ключа, уже встроенного в продукт.
Ну, просто удалите лишние символы, такие как "1", "l", "0", "o" из ваших ключей. Разбейте строку лицензионного ключа на группы символов.
Простой ответ - независимо от того, какую схему вы используете, ее можно взломать.
Не наказывайте честных клиентов с помощью системы, предназначенной для предотвращения хакеров, так как хакеры взломают ее независимо от этого.
Простой хешированный код, связанный с их электронной почтой или подобным, вероятно, достаточно хорош. Аппаратные идентификаторы всегда становятся проблемой, когда людям нужно переустанавливать или обновлять оборудование.
Хорошая тема по этому вопросу: http://discuss.joelonsoftware.com/default.asp?biz.5.82298.34
При генерации ключа не забудьте объединить версию и номер сборки со строкой, по которой вы вычисляете хеш. Таким образом, не будет ни одного ключа, который разблокирует все, что вы когда-либо выпускали.
После того, как вы найдете некоторые ключи или патчи в http://astalavista.box.sk/, вы поймете, что вам удалось сделать что-то достаточно популярное, чтобы кто-то потрудился взломать. Радуйтесь!
Я являюсь одним из разработчиков платформы лицензирования программного обеспечения Cryptolens и работаю над системами лицензирования с 14 лет. В этом ответе я включил несколько советов, основанных на опыте, приобретенном за эти годы.
Лучший способ решить эту проблему - настроить сервер лицензионных ключей, который будет вызывать каждый экземпляр приложения для проверки лицензионного ключа.
Преимущества сервера лицензионных ключей
Преимущества использования сервера лицензионных ключей:
- Вы всегда можете обновить или заблокировать лицензионный ключ с немедленным вступлением в силу.
- каждый лицензионный ключ может быть привязан к определенному количеству компьютеров (это помогает предотвратить публикацию лицензионного ключа в Интернете для использования другими пользователями).
Соображения
Хотя проверка лицензий в Интернете дает вам больший контроль над каждым экземпляром приложения, подключение к Интернету не всегда присутствует (особенно если вы работаете с крупными предприятиями), поэтому нам необходим другой способ проверки лицензионного ключа.
Решение состоит в том, чтобы всегда подписывать ответ лицензионного ключа от сервера, используя криптосистему с открытым ключом, такую как RSA или ECC (возможно, лучше, если вы планируете работать на встроенных системах). Ваше приложение должно иметь только открытый ключ для проверки ответа лицензионного ключа.
Таким образом, в случае отсутствия подключения к Интернету, вы можете использовать предыдущий ответ лицензионного ключа. Обязательно сохраните в ответе и дату, и идентификатор компьютера и убедитесь, что он не слишком старый (например, вы разрешаете пользователям оставаться в автономном режиме не более 30 дней и т. Д.) И что ответ с лицензионным ключом принадлежит правильному устройству.
Обратите внимание, что вы всегда должны проверять сертификат ответа лицензионного ключа, даже если вы подключены к Интернету, чтобы убедиться, что он не был изменен после того, как он покинул сервер (это все еще нужно сделать, даже если ваш API к сервер лицензионных ключей использует https)
Защита секретных алгоритмов
Большинство приложений.NET можно довольно легко реверсировать (есть и дизассемблер, предоставленный Microsoft для получения кода IL, и некоторые коммерческие продукты могут даже получать исходный код, например, в C#). Конечно, вы всегда можете запутать код, но он никогда не будет на 100% безопасным.
В большинстве случаев цель любого решения по лицензированию программного обеспечения состоит в том, чтобы помочь честным людям быть честными (т. Е. Честные пользователи, которые готовы платить, не забывают платить по истечении пробного периода и т. Д.).
Однако у вас все еще может быть какой-то код, который вы никоим образом не хотите разглашать общественности (например, алгоритм для прогнозирования цен на акции и т. Д.). В этом случае единственный способ - создать конечную точку API, которую ваше приложение будет вызывать каждый раз, когда должен выполняться метод. Требуется подключение к Интернету, но это гарантирует, что ваш секретный код никогда не выполняется на клиентском компьютере.
Реализация
Если вы не хотите реализовывать все самостоятельно, я бы порекомендовал взглянуть на этот учебник (часть Cryptolens)
Помимо того, что уже было заявлено....
Любое использование приложений.NET по своей природе может быть взломано из-за проблем со средним языком. Простая разборка кода.NET откроет ваш продукт любому. В этот момент они могут легко обойти ваш лицензионный код.
Вы даже не можете использовать аппаратные значения для создания ключа больше. Виртуальные машины теперь позволяют кому-то создавать образ "лицензированной" машины и запускать его на любой платформе, которую они выберут.
Если это дорогое программное обеспечение, есть другие решения. Если это не так, просто сделайте это достаточно сложным для случайного хакера. И принять тот факт, что в конечном итоге будут нелицензионные копии.
Если ваш продукт сложен, проблемы, связанные с поддержкой, создадут вам некоторую защиту.
Движок C# / .NET, который мы используем для генерации лицензионного ключа, теперь поддерживается как открытый исходный код:
https://github.com/appsoftware/.NET-Licence-Key-Generator.
Он основан на системе "Partial Key Verification", которая означает, что в ваш дистрибутив должен быть скомпилирован только поднабор ключей, которые вы используете для генерации ключа. Вы сами создаете ключи, поэтому реализация лицензии является уникальной для вашего программного обеспечения.
Как указывалось выше, если ваш код можно декомпилировать, то относительно легко обойти большинство систем лицензирования.
Я твердо верю, что только система лицензирования на основе криптографии с открытым ключом является правильным подходом, потому что вам не нужно включать необходимую информацию для генерации лицензии в ваш исходный код.
В прошлом я много раз пользовался библиотекой лицензирования Treek, потому что она полностью удовлетворяет этим требованиям и предлагает действительно хорошую цену. Он использует одинаковую лицензионную защиту для конечных пользователей и самого себя, и никто не взломал это до сих пор. Вы также можете найти хорошие советы на сайте, чтобы избежать пиратства и взлома.
Я не знаю, насколько тщательно вы хотите получить
но я считаю, что.net может получить доступ к серийному номеру жесткого диска.
Вы могли бы заставить программу прислать вам это и что-то еще (например, имя пользователя и MAC-адрес ник)
Вы вычисляете код на основе этого и отправляете им по электронной почте ключ обратно.
они не дадут им переключаться между машинами после того, как у них будет ключ.
Я использовал Crypkey в прошлом. Это один из многих доступных.
Вы можете защищать программное обеспечение только до определенной степени с любой схемой лицензирования.
Вы можете использовать бесплатное решение третьей стороны, чтобы справиться с этим для вас, например Quantum-Key.Net. Это бесплатно и обрабатывает платежи через PayPal через страницу веб-продаж, которую он создает для вас, выдачу ключей по электронной почте и блокирует использование ключей на конкретном компьютере для предотвратить пиратство.
Вам также следует позаботиться о том, чтобы запутать / зашифровать ваш код, иначе его можно легко восстановить с помощью таких программ, как De4dot и.NetReflector. ConfuserEx - это хороший обфускатор свободного кода, быстрый и простой в использовании и более эффективный, чем дорогие альтернативы.
Вы должны запустить ваше законченное программное обеспечение через De4Dot и.NetReflector, чтобы перепроектировать его и посмотреть, что взломщик увидит, если они сделают то же самое, и убедиться, что вы не оставили какой-либо важный код открытым или скрытым.
Ваше программное обеспечение все еще может быть взломано, но для обычного взломщика вполне может быть достаточно отложить его, и эти простые шаги также предотвратят извлечение и повторное использование вашего кода.
https://github.com/0xd4d/de4dot
https://www.red-gate.com/dynamic/products/dotnet-development/reflector/download
Единственный способ сделать все, что вы просили, это потребовать доступ в Интернет и проверку с помощью сервера. Прикладная программа должна войти на сервер с ключом, а затем вам необходимо сохранить детали сеанса, такие как IP-адрес. Это предотвратит использование ключа на нескольких разных машинах. Это обычно не очень популярно среди пользователей приложения, и если это не очень дорогое и сложное приложение, оно того не стоит.
Вы могли бы просто иметь лицензионный ключ для приложения, а затем проверить клиентскую сторону, если ключ хороший, но его легко распространить среди других пользователей, и с помощью декомпилятора можно генерировать новые ключи.
Я реализовал однократную активацию через Интернет в программном обеспечении моей компании (C# .net), для которого требуется лицензионный ключ, который ссылается на лицензию, хранящуюся в базе данных сервера. Программное обеспечение попадает на сервер с ключом и получает лицензионную информацию, которая затем шифруется локально с использованием ключа RSA, сгенерированного из некоторых переменных (комбинация CPUID и других элементов, которые не часто меняются) на клиентском компьютере, а затем сохраняет его в реестр.
Это требует некоторого кодирования на стороне сервера, но оно очень хорошо сработало для нас, и я смог использовать ту же систему, когда мы расширились до программного обеспечения на основе браузера. Он также дает продавцам отличную информацию о том, кто, где и когда используется программное обеспечение. Любая система лицензирования, которая обрабатывается только локально, полностью уязвима для эксплуатации, особенно с учетом.NET. Но, как все говорили, ни одна система не является полностью безопасной.
По моему мнению, если вы не используете веб-лицензирование, нет никакой реальной причины для защиты программного обеспечения вообще. Из-за головной боли, которую может вызвать DRM, несправедливо по отношению к пользователям, которые фактически заплатили за это.
Я знаю, что это старый вопрос, но я упомянул об этом, когда переписывал процесс лицензирования для одного из своих приложений.
Прочитав множество мнений и опираясь на прошлый опыт работы с лицензионными кодами, я придумал этот процесс.
public static class LicenseGenerator
{
private static string validChars = "ACEFHJKMNPRSTUVWXYZ234579";
private static Random rnd = new Random(Guid.NewGuid().GetHashCode());
/// <summary>
/// Generate a license code
/// </summary>
/// <param name="length">length of each phrase</param>
/// <param name="number">number of phrases separated by a '-'</param>
/// <returns></returns>
public static string GetNewCode(int length, int number)
{
string license = string.Empty;
for (int numberOfPhrases = 0; numberOfPhrases < number; numberOfPhrases++)
{
license += getPhrase(length);
if (numberOfPhrases < number)
license += "-";
}
return license.TrimEnd('-');
}
/// <summary>
/// generate a phrase
/// </summary>
/// <param name="length">length of phrase</param>
/// <returns></returns>
private static string getPhrase(int length)
{
string phrase = string.Empty;
for (int loop = 0; loop < length; loop++)
{
phrase += validChars[rnd.Next(validChars.Length)];
}
return phrase;
}
}
Вы действительно не хотите предоставлять код с похожими буквами; это создает беспорядок, когда конечный пользователь вводит его. Такие буквы, как 6 и G, B и 8, L, I и 1. Конечно, если они вам нужны, вы всегда можете добавить их обратно ... Приведенный выше код сгенерирует лицензию типа xxxx-xxxx-xxxx-xxxx, используя символы в «validChars». Вызов GetNewCode(4, 4) вернет код, подобный приведенному выше.
Я использую функции Azure для регистрации, а затем проверяю код. Когда мое приложение регистрирует код, оно генерирует зашифрованный хэш с элементами, уникальными для установки, устройства и/или пользователя. Он предоставляется функции регистрации и хранится вместе с ключом в БД в Azure.
Проверка повторно генерирует ключ и предоставляет ему лицензионный код, IP-адрес (который в моем случае не изменится, а если и изменится, то его все равно нужно будет обновить) и восстановленный хэш, после чего функция Azure возвращает, если приложение лицензированный. Я храню «временный» ключ на их сервере, который позволяет приложению работать в течение определенного периода времени без возражений.
Конечно, мое приложение должно быть в сети, чтобы оно работало в любом случае.
Таким образом, конечным результатом является простой ключ для ввода конечным пользователем и простой процесс управления лицензией на серверной части. Я также могу аннулировать лицензию, если это будет необходимо.
Полное предотвращение компьютерного пиратства невозможно. Вы можете предотвратить случайное пиратство, и именно это делают все решения по лицензированию.
Лицензирование на узле (машине) заблокировано, если вы хотите предотвратить повторное использование лицензионных ключей. Я уже почти год пользуюсь Cryptlex для своего программного обеспечения. У него также есть бесплатный план, поэтому, если вы не ожидаете слишком много клиентов, вы можете использовать его бесплатно.
Как и несколько других упомянутых, я являюсь огромным противником враждебности по отношению к клиентам по умолчанию - то, на что индустрия лицензирования печально известна. Поэтому я остановлюсь на хорошем решении вашей проблемы, которое также предлагает хороший пользовательский UX.
Для начала вы упомянули, что у вас есть "ограниченная" версия программного обеспечения, которую вы используете, чтобы попытаться преобразовать клиентов в "апгрейд" для получения дополнительных функций. Итак, вам нужны лицензии для вашего продукта, например, клиент может приобрести лицензию для Feature-X или Feature-Y.
Я создал Keygen с учетом этого типа лицензирования. Keygen - это лицензионный REST API, который позволяет управлять учетными записями пользователей, лицензиями, а также отслеживать использование / ассоциации компьютеров.
Я хотел бы настроить два типа лицензий (политика в Keygen), где один является базовой политикой для ограниченной бесплатной версии, а другой - политикой для платной версии.
Я не уверен, что вы используете для платежей, но давайте предположим, что вы используете что-то вроде Stripe (довольно стандартного в настоящее время), который предлагает веб-хук. У Keygen также есть webhooks (используете ли вы это или нет, все это по-прежнему применимо). Вы можете интегрировать Keygen для общения с вашим платежным провайдером с помощью веб-крючков с обеих сторон (подумайте: customer.created
-> создать базовую лицензию для клиента, license.created
-> взимать плату с клиента за новую лицензию).
Таким образом, используя webhooks, мы можем автоматизировать создание лицензий для новых клиентов. Так как насчет проверки лицензии в самом приложении? Это может быть сделано различными способами, но наиболее популярным является требование, чтобы ваш клиент ввел длинный лицензионный ключ в поле ввода, которое затем можно проверить; Я думаю, что это ужасный способ проверки лицензии в вашем приложении.
Почему я так думаю? Ну, во-первых, вы требуете от своего клиента ввести утомительно длинный лицензионный ключ, предназначенный для потребления машины, а во-вторых, вы требуете, чтобы вы и ваш клиент отслеживали указанный утомительно длинный лицензионный ключ.
Ладно, а какая альтернатива? Я думаю, что лучшая альтернатива - сделать то, к чему привыкли все ваши клиенты: позволить им создать учетную запись для вашего продукта, используя адрес электронной почты / пароль. Затем вы можете связать все их лицензии и их машины с этой учетной записью. Так что теперь вместо ввода лицензионного ключа они могут просто войти в систему, используя свои учетные данные.
Какое преимущество это дает вам? Во-первых, это избавляет вас и ваших клиентов от необходимости отслеживать лицензионные ключи, поскольку все они обрабатываются за кулисами внутри их учетной записи пользователя, и самое главное: теперь вы можете предлагать своим клиентам лицензию и машину для самообслуживания. активация! то есть, поскольку все их лицензии и машины связаны с их учетной записью пользователя, вы можете предложить им приобрести лицензию, когда они запустят ваше приложение на нераспознанной машине.
Теперь перейдем к проверке лицензии: всякий раз, когда ваш клиент входит в ваше приложение со своим адресом электронной почты / паролем, вы можете запросить у его учетной записи пользователя лицензии, которыми они владеют, чтобы определить, могут ли они использовать Feature-X или Feature-Y. А поскольку ваше приложение теперь самообслуживается, вы можете позволить своим клиентам приобретать дополнительные функции прямо из вашего приложения!
Итак, мы внедрили тонну автоматизации в нашу систему лицензирования, мы можем лицензировать отдельные функции (то есть ограниченную или полную версию), мы предложили удивительный UX для наших клиентов, и мы также решили одну из главных причин для запросов поддержки: восстановление лицензионного ключа.
В любом случае, это долго, но, надеюсь, кому-то поможет!
Я решил это, связав свою программу с сервером Discord, где она проверяет в конкретном чате, существует ли ключ продукта, введенный пользователем, и все еще действителен. Таким образом, чтобы получить ключ продукта, пользователь будет вынужден взломать Discord, а это очень сложно.