Шароварная криптография: Выбираем алгоритм для системы лицензирования

December 24th, 2008 Begemot Posted in Шаровароварение

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

  1. Приложение должно иметь возможность убедиться, что введеный ключ – это именно оригинальный, неизмененый ключ который сделали. 
  2. Злоумышленник не должен иметь возможности создать свой валидный клю – избегаем кейгенов

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

Самый распространенный метод ассиметричной криптографии – RSA. Чуть менее распространеный, в силу свой молодости – DSA. В кратце плюсы каждого алгоритма

RSA:

  • Более зрелый, проверенный временем. Больше реализаций и примеров использования.
  • Возможность использовать как для создания подписи, так и для шифрования. (последнее нам не надо, но в потенциально может пригодится)

DSA:

  • Легче в реализации, если писать самому, а не использовать готовые библиотеки
  • Меньше длина подписи – 40 байт.
  • Делает все что нам нужно
Ещё есть алгоритмы на эллиптических кривых (тот же ECDSA, например), которые работают быстрее и требуют меньших размеров ключей, но они ещё менее распространены и сложны для понимания нематематиками

Я выбрал (мне выбрали:)) DSA.

Дальше нам нужно сделать следующе

  1. Сгенерировать пару ключей.
  2. Выбрать готовую реализацию алгоритма DSA или RSA и прикрутить ее к своему проекту. Или  второй вариант – написать ее самому, как показывает опыт одного человека, это вполне реально, хотя не уверен что я бы лично рискнул:)
  3. Написать две процедуры: подписи лицензии для кейгена и проверки для приложения.

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

Related:

35 Responses to “Шароварная криптография: Выбираем алгоритм для системы лицензирования”

  1. Вообще то, все это работает только если нет возможности изменить экзешник, иначе обходится на раз:
    1. создаем пару ключей
    2. создаем фейковую лицензию
    3. заменяем открытый ключ в программе созданным в шаге 1
    4. подписываем созданную на шаге 2 лицензию закрытым ключом, созданным на шаге 1
    5. вуаля – программа принимает ключ
    Поэтому для такого вида защиты мастерами обычно создается патч и кейген

  2. 2 Sergey:

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

  3. Ippi обогнал меня с ответом:) Дополню только, что саму программу наверняка сломать еще легче, так как защиту может и отсутствовать. А так я слабости хорошо представляю, но цель сделать хорошую гибкую лицензию и исключить вариант кейгена. Все-таки кейген намного хуже чем кряк.

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

  5. да, кстати, про использования значений из публичного ключа это прикольная идея, надо подумать куда это прикрутить.

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

  6. 2 Norfolc

    Замена ключей – тоже своего рода смена формата. В любом случае, технические сложности — ничто перед процедурой обмена ключей, особенно когда клиентов уже много.

    2 Begemot.

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

  7. Все, что ты написал очень привлекательно, но есть одно “но”.
    Ключи защищены подписью, сгенерить их кейгеном не получается. Но вот только нашелся кулхацкер, который честно купил программу по краденой кредитке. И ему был честно выслан настоящий подписанный ключ. И валяется теперь этот ключ по всему интернету. Только ленивый не найдет.

    Мы же, чтобы уберечься от патчеров, следуем принципу “release often, release early”. И посему, подходит этот мошеннический ключ ко всем версиям программы… И тем, что есть, и тем, что будут.

    Что бум делать? Менять ключи подписи? Плохо. Придется перевыпускать все ключи и рассылать их всем честным пользователям. А ведь не факт еще, что все пользователи их нормально обновят. А это означает ураганный геморрой с саппортом и масса отрицательных эмоций у пользователей…

  8. 0xDEADBEEF, поэтому, чтобы такое не происходило, нужно привязываться к железу (получать HardwareID на этапе покупки или делать систему активации с ограниченным числом активаций).
    Ну ещё можно в следующих версиях заносить “ворованный” ключ в чёрный список.

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

  10. 0xDEADBEEF, ключ, защищённый подписью, может (должен?) быть персонализирован, т.е. содержать в себе имя и контакт владельца. С одной стороны, это может удержать приобретателя ключа от раздачи его налево и направо, а с другой стороны – многие пользователи чувствуют себя некомфортно, когда программа пишет, что зарегистрирована не на их имя.

  11. […] затянулся, но все же вернемся к криптографии. Про выбор алгоритма я писал в прошлый раз, в этот раз как это можно […]

  12. Берешь Армадилу или еще какой Протектор и не ибешь себе моск 🙂

    Активация спасает от всех этих проблем, но не ко всем типам продуктов подходит….

  13. ключи лучше свои иметь что бы легко можно было сменить протектор… или ос 🙂

  14. Зачем?

  15. А вдруг?

  16. Решай проблемы по мере поступления…

  17. Мой пост кто-то стер 🙂

    Я все про длину ключей – ты делаешь персонализированный ключ да еще и подписываешь его. Какая длина получается?
    40 байт подпись плюс хотя бы 10 байт на сам ключ, переводим в base64 и получаем нифига не короткий ключ.
    Зачем вообще подпись нужна? Это же тупое сравнение. Используй асимметрику для шифрования ключа и все.

  18. Я не стирал, может барабашка:)
    длина около 170 символов, типа как у аспра, ключ персонализированный + куча информации – дата, референс намбер, мыло… за все время на длину жаловались только два человека, че экономить то ?
    Подпись нужна что бы кейген не сделать… собственно подпись это и есть ассиметрика:)

  19. У меня 32 символа ввести не могут 🙂

    Просто я не могу понять смысл применения цифровой подписи.
    Тот же RSA можно применять как для подписи так и для шифрования, правильно? Ты сперва кодируешь информацию об ордере, а потом ее подписывашь. Можно просто асимметрикой шифровать информацию ордера. Без приватного ключа кейген тоже не сделаешь, а ключик короче получается.

  20. В алгоритме RSA для подписи используется приватный ключ, а для его проверки – публичный (вшит в программу). Шифровать данные в ключе не нужно. Нужно только их подписать. И этого вполне достаточно, чтобы удостовериться в правильности ключа.
    А шифрование данных происходит публичным ключем. И расшифровать можно только приватным. Поэтому для шаровары это не подходит – прийдется вшивать приватный ключ в программу, что есть глупо.
    А длина ключа – не проблема. Можно ключ слать файлом, а можно и в обычном текстовом виде и написать, чтобы сделали Copy/Paste.

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

    С эллиптическими кривыми ты тоже не разобрался. Длина ключа не имеет значения, тебе важна длина подписи. У DSA и ECDSA длина подписи одинаковая. Это – два.

    Если просто подписать серийник и проверять его валидность в коде, то достаточно просто пропатчить проверку – IF signature = true. Если серийник зашифровать, что прийдется прошивать новый публичный ключ, а это сделать не так то просто, он у меня использвуется в алгоритме самой программы.

  22. Как раз запутался ты.
    Вся соль в том, что шифрование производится публичным ключем, а расшифровка – приватным.
    Прочитай хотябы википедию: http://ru.wikipedia.org/wiki/RSA
    Сделано это для того, чтобы, например, я мог выложить в сеть свой публичный ключ и кто угодно мог послать мне сообщение, которое смогу только я прочитать и никто иной (ведь дешифровка производится привтным ключем).
    И если этот кто-то хочет, чтобы я ему ответил шифрованным сообщением, то он сообщит мне свой публичный ключ.

  23. Нифига! Сама природа RSA подразумевает, что одним ключом шифруешь, другим расшифровываешь. Да, в Вики приведен один из вариантов использования, но наоборот тоже работает. Проверено.

  24. Да, согласен. можно шифровать и приватным ключем (Прив.К), а расшифровывать публичным (Публ.К). Только это особого смысла не имеет.
    С таким же успехом можно на “лицензинный ключ” (ЛК) наложить Base64 – будет та же самая шифровка. Ведь Публ.К вшит в программу и не составляет труда его оттуда получить и самому расшифровать ЛК.
    Поэтому кракеру будет достаточно иметь расшифрованный ключ и пропатчить уже не проверку подписи, как в моём случае, а вызов дешифрации.

  25. Не совсем так:

    – кейген не сделаешь. Это же была главная задача?
    – чтобы расшифровать ключ его сперва надо скардить. без ключа дело не пойдет. У тебя же ключ открытый и достаточно отломить подпись.
    – тупой проверки IF тут нет, зашифрованные данные ключа используются в программе
    – ключик все же вдвое короче твоего – 95 base32 символов.
    Ой, даже в 4 раза короче, у тебя же base64

  26. 2 topmedia:

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

    Кроме того, в вашей схеме нужно иметь механизм проверки валидности расшифрованных данных; в общем случае это – избыточные данные, причём, чтобы стать сопоставимым по уровню надёжности с DSA, этот механизм должен задействовать сопоставимый объём избыточных данных (ну ладно, вдвое меньший, но это мало что меняет). Без такого механизма кто-нибудь рано или поздно сгенерирует лицензию на “TopMedia” или на “Registered User”, а это почти так же плохо, как кейген.

  27. topmedia: Мой пост кто-то стер

    Тут кстати есть предположение что твой коммент просто к другому посту:) Это не он тут
    http://begemotov.net/creator/shareware/sharovarnaya-kriptografiya-ili-pishem-sistemu-litsenziy-na-kolenke-chast-pervaya/ ?

  28. 2 Ippi: что-то я совсем заработался, не в два раза, а на 20%. Все-равно много.

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

    С подписью нет никакой возможности спрятать в ключе эту константу, а такая схема используется почти во всех протекторах.

    Длина ключа для меня очень важна. При нынешних 30 символах у меня несколько раз в неделю жалуются что не ключ не работает 🙁

    2Begemot: Да, промахнулся. Извини, что необоснованно наехал.

  29. topmedia: С подписью нет никакой возможности спрятать в ключе эту константу, а такая схема используется почти во всех протекторах.

    А что мешает сделать константу частью ключа? У меня так и есть кстати…

    topmedia:
    Длина ключа для меня очень важна. При нынешних 30 символах у меня несколько раз в неделю жалуются что не ключ не работает

    У меня при 170 символах и в голову никому не приходит вводить его вручную, соответственно никто не жалуется…

  30. В открытом виде давать константу? Или ключ все-таки шифруется?

    У тебя видимо нет клиенток-домохозяек 🙂 Можешь не верить, но они ключик на листочек записывают и всегда вводят ручками.

  31. topmedia: В открытом виде давать константу? Или ключ все-таки шифруется?

    ты же сам сказал раньше

    topmedia: Естественно, первый же кардер сможет получить константу для дешифрации данных имея на руках валидный ключ

    так что степерь секртности не отличается:)

    topmedia: У тебя видимо нет клиенток-домохозяек Можешь не верить, но они ключик на листочек записывают и всегда вводят ручками.

    А ты в письме грозно пишешь – только копируйте и вставляйте! 🙂

  32. Возможно ты прав, хотя непривычно давать ключ в открытом виде.

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

  33. ну да иногда присылают исковерканный ключ и говорят что не работает, отсылаю новый что делать…

  34. Сорри за некропостинг.
    К вопросу о инкапсуляции имени, email’а и еще какой-то информации. Как я понял, суть цифровой подписи состоит не в генерации зашифрованного сообщения, содержащего исходные данные, а подписывании дайджеста (хэша) сообщения – как я понял, используется обычно SHA-1 – в результате ключик можно получить довольно короткий и фиксированной длинны. Из минусов – в ключе не передается какая-либо информация. Но для задачи генерации лицензии можно же попросить пользователя, чтобы он ввел имя, email, название организации и ключ, и сравнивать хэш этих данных с тем что в ключе. В принципе, к хэшу уже можно прицепить и некоторый набор данных – даты, ключевое значение для работы программы, еще что-либо коротенькое фиксированного размера. Если я все правильно понял, то остался такой вопрос – хочу кейген на php написать, openssl функции сами хэш высчитывают при подписывании или я сам могу хэш посчитать, дополнить его, и сгенерировать подпись по этим данным?

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

  35. В сврусе была длинная дискуссия недавно про короткие vs длинные ключи. Большинство считают что короткие рулят, но я не согласен. Мне длинные ключи проблем не доставляют, а преимуществ имеют много. На мой взгляд заставлять пользователя вводить еще какие-то данные не есть гуд, проще все таки скопипайстить 1 длинный ключ.

    Я собираю всю информацию в массив данных, типа так.
    служебные биты, 6 бит длина имени, имя, 8 длина коммента, коммента, дата генерации, версии…. потом вычисляю от массива подпись и цепляю к оригинальной строке, кодирую в base64 и получаю ключ. В программе обратный алгоритм.

    По остальным вопросам не буду путать, сам давно разбирался забыл уже:)