Как защитить код Python?


632

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

Если мы распространяем файлы .py или даже .pyc, будет легко (декомпилировать и) удалить код, который проверяет файл лицензии.

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

Есть ли хороший способ справиться с этой проблемой? Желательно с готовым решением.

Программное обеспечение будет работать в системах Linux (поэтому я не думаю, что py2exe справится с задачей).


25
py2exe просто хранит файлы байт-кода .pyc в архиве .zip, так что это определенно не решение. Тем не менее, это может быть полезно в сочетании с подходящим сценарием запуска для запуска под Linux
Ber


Это наиболее полный ответ на ваш вопрос: wiki.python.org/moin/Asking%20for%20Help/…
Майк

Ответы:


378

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

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

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


157
Даже если код проверки лицензии было трудно реконструировать, потому что он написан на C, разве не было бы относительно легко удалить вызовы кода проверки лицензии?
Блэр Конрад

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

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

11
@Blair Conrad: Нет, если код проверки лицензии тоже скрывает функциональность. Напримерmylicensedfunction(licenseblob liblob, int foo, int bar, std::string bash)
Брайан

8
Я на самом деле видел коммерческий код Python, поставляемый как встроенный Python внутри библиотеки C. Вместо того, чтобы преобразовывать некоторые части кода в C, они скрывают весь код Python внутри защитного слоя C. Затем, если им нужен модуль, импортируемый Python, они пишут тонкое расширение Python поверх C. Открытый исходный код - намного более простой образ жизни.
Майк Маккернс

454

"Есть ли хороший способ справиться с этой проблемой?" Нет. Ничто не может быть защищено от обратного проектирования. Даже встроенное ПО на DVD-машинах было перепроектировано, и ключ шифрования AACS был открыт. И это несмотря на то, что DMCA считает это уголовным преступлением.

Поскольку ни один технический метод не может помешать вашим клиентам читать ваш код, вы должны применять обычные коммерческие методы.

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

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

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

  4. Предлагайте индивидуальные настройки по привлекательным ценам, так что они скорее заплатят, а вы создадите и поддержите усовершенствования.

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

  6. Предложите это как веб-сервис. SaaS не требует загрузки для клиентов.


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

Это правда. Обратный инжиниринг выполним, но в большинстве ситуаций дорог. @ S.Lott, я считаю, что пункт 6 имеет большее значение в зависимости от вопроса. Если исходный код действительно нуждается в защите, он должен быть удален от конечного пользователя.
Делали

7
Вопрос: «Есть ли хороший способ защитить мою семью и себя от убийства злоумышленниками во сне?» Интернет: «Нет. Любого можно достать, и ни одно жилище не может быть на 100 процентов непроницаемым. Смертная человеческая семья - неподходящий инструмент для работы».
Простой алгоритм

Точка 5 не может быть применена при том же предположении, что она может быть подвергнута обратной инженерии и взломана.
jjmontes

313

Python не тот инструмент, который вам нужен

Вы должны использовать правильный инструмент, чтобы делать правильные вещи, и Python не был разработан, чтобы быть запутанным. Это наоборот; в Python все открыто или легко раскрывается или изменяется, потому что это философия языка.

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

Запутывание действительно трудно

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

Наличие юридического требования - хороший способ

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

Защита кода переоценена

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


17
Python не тот инструмент, который вам нужен. Мальболге есть. :)
Johndodo

8
Хороший ответ, но "случайный юридический вопрос"? В самом деле? Где вы живете, что у вас есть какие-либо юридические проблемы, которые являются случайными?
Марк Э. Хааз

1
Я думаю, что если у нас есть частота - как часто взламывается дорогой запутанный код - мы могли бы сказать о целесообразности использования Python и запутанного кода.
sergzach

Если у вашего кода есть интересные функции, тот, кто смог его использовать не по назначению, распространит его @Macke
Delali

1
Как в мире вы "легко обнаружите, если кто-то делает"?
Make42

145

Компилировать Python и распространять двоичные файлы!

Разумная идея:

Используйте Cython , Nuitka , Shed Skin или что-то подобное для компиляции кода Python в C, а затем распространяйте свое приложение как двоичные библиотеки Python (pyd).

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

Cython становится все более и более совместимым с CPython, поэтому я думаю, что он должен работать. (На самом деле я рассматриваю это для нашего продукта. Мы уже создаем некоторые сторонние библиотеки в виде pyd / dll, поэтому доставка нашего собственного кода Python в виде бинарных файлов не является для нас слишком большим шагом.)

Смотрите этот пост в блоге (не мной), чтобы узнать, как это сделать. (спасибо @hithwen)

Сумасшедшая идея:

Вероятно, вы могли бы заставить Cython хранить C-файлы отдельно для каждого модуля, а затем просто объединить их все и построить их с тяжелым встраиванием. Таким образом, ваш модуль Python является довольно монолитным, и на него трудно ориентироваться обычными инструментами.

Вне сумасшедшего

Возможно, вы сможете создать один исполняемый файл, если сможете статически связывать (и оптимизировать) среду выполнения Python и все библиотеки (dll). Таким образом, было бы трудно перехватывать вызовы в / из python и любых библиотек фреймворка, которые вы используете. Это не может быть сделано, если вы используете код LGPL.


Будет ли компилирование с помощью Cython работать с приложением Python 3.4 Django, или оно может работать без огромных усилий?
Даниил

@ Даниель: Не уверен. Не пробовал на Джанго. Не стесняйтесь отправить новый вопрос об этом.
Мак


4
@mlvljr FWIW, IMHO, компиляция в двоичные файлы - хороший компромисс между продажей всех ваших секретов и попыткой защиты от обратного инжиниринга класса NSA. Esp, если у вас есть большая база кода Python и причины быть параноиком. ;)
Маке

2
POST hithwen сейчас недействителен.
qg_java_17137

58

Я понимаю, что вы хотите, чтобы ваши клиенты использовали возможности Python, но не хотите раскрывать исходный код.

Вот мои предложения:

(a) Напишите критические фрагменты кода в виде библиотек C или C ++, а затем используйте SIP или swig, чтобы представить API C / C ++ в пространстве имен Python.

(б) Используйте Cython вместо Python

(c) В обоих случаях (a) и (b) должна быть возможность распространять библиотеки в виде лицензионного двоичного файла с интерфейсом Python.


1
Другие возможности в том же духе: Shed Skin code.google.com/p/shedskin и Nuitka kayhayen24x7.homelinux.org/blog/nuitka-a-python-compiler
TryPyPy

Я только что посмотрел на Shed Skin, как предложено TyPyPy, и, похоже, это действительно хороший материал!
Филип

34

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

[EDIT] Ответ на комментарий Ника:

Ничего не получено и ничего не потеряно. Клиент имеет то, что он хочет (и заплатил за это, так как он сделал изменение самостоятельно). Так как он не выпускает изменения, как будто это не случилось для всех остальных.

Теперь, если клиент продает программное обеспечение, он должен изменить уведомление об авторских правах (что является незаконным, поэтому вы можете подать в суд и выиграете -> простой случай).

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

Опять же у нас есть два случая: первоначальный клиент продал всего несколько копий. Это означает, что они все равно не заработали много денег, так зачем беспокоиться. Или они продаются в объеме. Это означает, что у вас больше шансов узнать о том, что они делают, и что-то с этим сделать.

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


Что если они выпускают программное обеспечение для клиентов, а клиент изменяет его внутри, не переиздавая его?
Ник Т

@Nick: никак не меняет ситуацию. Смотрите мои правки.
Аарон Дигулла

6
+1 за кражу идей назад. Зачем ограничивать свои возможности обслуживания клиентов своими собственными решениями, если вы видите, как другие улучшают ваше решение и, соответственно, улучшают ваш собственный продукт? «Если у вас есть яблоко, а у меня есть яблоко, и мы обмениваем эти яблоки, то у вас и у меня все еще будет по одному яблоку. Но если у вас есть идея, и у меня есть идея, и мы обмениваемся этими идеями, то у каждого из нас будет две идеи. "
Иордания

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

1
@Skandix Как именно это будет работать? Загрузка вашей работы в Интернете не навредит вам. Это начнёт причинять вам вред, если многие найдут его И вместо этого будут платить покупателям. Кража кода - это миф. «Мои знания бесплатны, мое время дорого» (не уверен, кто это сказал).
Аарон Дигулла

34

Вы смотрели на Pyminifier ? Он минимизирует, запутывает и сжимает код Python. Пример кода выглядит довольно неприятно для случайного обратного инжиниринга.

$ pyminifier --nonlatin --replacement-length=50 /tmp/tumult.py
#!/usr/bin/env python3
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ=ImportError
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱=print
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ巡=False
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ澨=object
try:
 import demiurgic
except ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ:
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Warning: You're not demiurgic. Actually, I think that's normal.")
try:
 import mystificate
except ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ:
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Warning: Dark voodoo may be unreliable.")
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺬ=ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ巡
class ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐦚(ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ澨):
 def __init__(self,*args,**kwargs):
  pass
 def ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ클(self,dactyl):
  ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ퐐=demiurgic.palpitation(dactyl)
  ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𠛲=mystificate.dark_voodoo(ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ퐐)
  return ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𠛲
 def ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐠯(self,whatever):
  ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱(whatever)
if __name__=="__main__":
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Forming...")
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺃ=ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐦚("epicaricacy","perseverate")
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺃ.ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐠯("Codswallop")
# Created by pyminifier (https://github.com/liftoff/pyminifier)

6
Хорошая идея в этом заключается в том, чтобы деморализовать любого, кто пытается расшифровать функциональность. Объедините это с Cython и некоторыми дополнительными модулями шифрования или интернет-звонками, и вы, вероятно, получите приз.
августа

Единственное, что удалось сделать этому пакету, - обмануть «обфускатор», заключающийся в том, что код запутан.
Маркроксор

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

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

Эта библиотека, кажется, не поддерживается, и дает мне ошибки отступа. Я использую Python 3.7
PV

25

Не надейтесь на запутывание. Как вы правильно сделали, он предлагает очень ограниченную защиту. ОБНОВЛЕНИЕ: Вот ссылка на статью которой приведен обратный инженерный обфусцированный код Python в Dropbox. Подход - переназначение кода операции - хороший барьер, но, очевидно, его можно победить.

Вместо этого, как упоминалось во многих постерах, сделайте это:

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

В качестве альтернативы, как делает отличная Python IDE WingIDE: раздайте код . Правильно, раздайте код и попросите людей вернуться за обновлениями и поддержкой.


1
Как эта крайняя идея. Получает огромную долю рынка и огромную долю рынка, тогда у вас очень большая клиентская база для поддержки и дополнений. Я также занимался этим вопросом, и все ответы о «лицензировании» в основном бычьи, потому что он не защищает от широко распространенного копирования, но не дает вам преимущества доли рынка.
Томас Браун

Но обновления также просто бесплатны ... так как они будут взимать плату за это? Разве это не просто поддержка?
Make42

Относительно бизнес-модели WingIDE: Поддержка - это услуга, программный продукт. Масштаб продуктов, сервис - нет. Поддержка - это только хорошая бизнес-модель, если нет другой бизнес-модели, то есть, если никто не будет покупать ваш продукт (по какой-либо причине), вы отдаете его, чтобы у вас была клиентская база, которая по крайней мере покупает ваши услуги.
Make42

20

Используйте Cython . Он скомпилирует ваши модули в высокопроизводительные C-файлы, которые затем могут быть скомпилированы в собственные двоичные библиотеки. По сути это необратимый код по сравнению с байт-кодом .pyc!

Я написал подробную статью о том, как настроить Cython для проекта Python, посмотрите его:

Защита исходников Python с помощью Cython


19

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


Да, но не в том случае, если вы распространяете эту точную версию Python со своим запутанным кодом.
Алекс

17

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

Таким образом, проверки лицензии могут быть выполнены в безопасности вашей собственной серверной комнаты.


+1 (назад к 0): кажется, единственно верное решение проблемы, если принять такой подход практичным для настройки.
интуитивно

10
Имейте в виду, что если ваш лицензионный веб-сервер будет недоступен или у клиентов не будет доступа к Интернету, ваши клиенты не будут рады, что они не смогут вести свой бизнес из-за потери доступа к проверкам лицензирования.
DevPlayer

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

1
@Джеффри: Это вернет вас туда, откуда вы начали - как защитить этот код. Чтобы быть более безопасным, вам нужно разместить некоторые ключевые функции на своем собственном сервере, поэтому замена его потребует значительных усилий (в какой момент, почему бы просто не запустить конкурента с открытым исходным кодом?)
странное размышление

14

Хотя идеального решения не существует, можно сделать следующее:

  1. Переместите некоторый критический фрагмент кода запуска в собственную библиотеку.
  2. Проведите проверку лицензии в собственной библиотеке.

Если бы вызов нативного кода был удален, программа все равно не запустилась бы. Если он не будет удален, лицензия будет применена.

Хотя это не кроссплатформенное или чисто Python-решение, оно будет работать.


3
Подход с использованием нативной библиотеки значительно упрощает программную обработку вашей системы лицензионных ключей, поскольку они могут использовать ваш собственный код и API для проверки своих лицензий.
Том Лейс

8
Так? Используйте RSA, чтобы подписать вашу лицензию, и пусть они переборят ваш закрытый ключ, скажем, состоящий из 1024 бит. Это возможно, но занимает много времени ... а значит - деньги.
Абган

12

Я думаю, что есть еще один способ защитить ваш код Python; часть метода запутывания. Я считаю, что была такая игра, как Mount and Blade или что-то, что изменило и перекомпилировало их собственный интерпретатор Python (оригинальный интерпретатор, который, я считаю, с открытым исходным кодом) и просто изменило коды OP в таблице кодов OP, чтобы они отличались от стандартных OP Python. коды.

Таким образом, исходный код python не изменен, но расширения файлов * .pyc отличаются, и коды операций не соответствуют общедоступному интерпретатору python.exe. Если вы проверили файлы данных игр, все данные были в исходном формате Python.

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

Например, вы можете в модифицированном интерпретаторе разрешить ему проверять наличие определенных комментариев или строк документации в вашем источнике. Вы можете иметь специальные OP-коды для таких строк кода. Например:

ОП 234 предназначен для строки исходного текста «# Авторские права я написал это» или скомпилирует эту строку в коды операций, которые эквивалентны «if False:», если отсутствует «# Copyright». По сути, отключение целого блока кода по неясной причине.

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

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

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


11

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


10

Я был удивлен, не увидев пиконкрет в любом ответе. Может потому что это новее, чем вопрос?

Это может быть именно то, что вам нужно (ред.).

Вместо того, чтобы запутывать код, он шифрует его и расшифровывает во время загрузки.

Со страницы Pypi :

Защитить рабочий процесс скрипта Python

  • your_script.py import pyconcrete
  • Pyconcrete подключит модуль импорта
  • когда ваш сценарий сделать импорт MODULE, pyconcrete импорт крюк будет пытаться найти MODULE.pyeпервый , а затем расшифровывать с MODULE.pyeпомощью _pyconcrete.pydи выполнить расшифрованные данные (как .pyc контента)
  • Зашифровать и расшифровать запись секретного ключа _pyconcrete.pyd (например, DLL или SO), секретный ключ будет скрыт в двоичном коде, его нельзя увидеть непосредственно в представлении HEX

9

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

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

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

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


8

Другая попытка усложнить кражу вашего кода - использовать jython, а затем использовать java obfuscator .

Это должно работать очень хорошо, так как jythonc переводит код Python в Java, а затем Java компилируется в байт-код. Так что, если вы запутаете классы, будет очень трудно понять, что происходит после декомпиляции, не говоря уже о восстановлении реального кода.

Единственная проблема с Jython заключается в том, что вы не можете использовать модули Python, написанные на языке c.


6

Как насчет подписи вашего кода стандартными схемами шифрования путем хеширования и подписывания важных файлов и проверки его методами открытого ключа?

Таким образом, вы можете выдать файл лицензии с открытым ключом для каждого клиента.

Кроме того, вы можете использовать Python Obfuscator, как этот (просто погуглил).


1
+1 за подпись; -1 для обфускатора Вы можете, по крайней мере, предотвратить изменение кода.
Али Афшар

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

Да, начальная загрузка в не Python.
Али Афшар

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

6

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


8
но тот факт, что он был пройден, означал, что они потерпели неудачу - суть в том, что не пытайтесь, а обращайтесь за правовой защитой
Chii

Есть ли какая-либо информация о том, как пройти этот механизм защиты?
Mitar

6

Лучшее, что вы можете сделать с Python, - это запутать вещи.

  • Удалите все строки документации
  • Раздайте только скомпилированные файлы .pyc.
  • заморозить это
  • Затенить ваши константы внутри класса / модуля, чтобы help (config) не показывал все

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

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


5

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

Запрет конкурентам использовать исходный код как свой собственный или написать свою вдохновленную версию того же кода, один из способов защиты - добавить подписи в логику вашей программы (некоторые секреты, чтобы можно было доказать, что код был украден у вас) и запутать Исходный код на Python, поэтому его трудно читать и использовать.

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

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

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

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


4

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

С учетом сказанного я просто проверял Google на предмет обмана в Python и не обнаруживал много чего-либо. В решении .Net, obsfucation будет первым подходом к вашей проблеме на платформе Windows, но я не уверен, есть ли у кого-нибудь решения для Linux, которые работают с Mono.

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

Все сводится к компромиссам. С одной стороны у вас есть простота разработки программного обеспечения на Python, в котором также очень трудно скрыть секреты. С другой стороны, у вас есть программное обеспечение, написанное на ассемблере, которое гораздо сложнее написать, но гораздо легче скрыть секреты.

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


4

Короче говоря:

  1. Зашифруйте ваш исходный код
  2. Напишите свой собственный загрузчик модулей Python для расшифровки кода при импорте
  3. Реализовать загрузчик модулей в C / C ++
  4. Вы можете добавить дополнительные функции в загрузчик модулей, например, анти-отладчик, контроль лицензий, привязку аппаратных отпечатков пальцев и т. Д.

Для более подробной информации, посмотрите этот ответ .

Если вам интересна тема, вам поможет этот проект - pyprotect .


3

Возможно иметь байт-код py2exe в зашифрованном ресурсе для модуля запуска C, который загружает и выполняет его в памяти. Некоторые идеи здесь и здесь .

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

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

Но, как уже говорили другие, если ваш код того стоит, обратные инженеры в конце концов преуспеют.


3

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

На GitHub есть библиотека с открытым исходным кодом. которая может помочь вам с проверкой лицензии.

Вы можете установить его, pip install licensingа затем добавить следующий код:

pubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"

res = Key.activate(token="WyIyNTU1IiwiRjdZZTB4RmtuTVcrQlNqcSszbmFMMHB3aWFJTlBsWW1Mbm9raVFyRyJd",\
                   rsa_pub_key=pubKey,\
                   product_id=3349, key="ICVLD-VVSZR-ZTICT-YKGXL", machine_code=Helpers.GetMachineCode())

if res[0] == None not Helpers.IsOnRightMachine(res[0]):
    print("An error occured: {0}".format(res[1]))
else:
    print("Success")

Вы можете узнать больше о настройке открытого ключа RSA и т. Д. Здесь .


2

Используйте тот же способ защиты двоичного файла c / c ++, то есть обфусцируйте каждое тело функции в исполняемом файле или двоичном файле библиотеки, вставьте инструкцию «jump» в начале каждой записи функции, перейдите к специальной функции для восстановления запутанного кода. Байт-код является двоичным кодом скрипта Python, поэтому

  • Сначала скомпилируйте скрипт Python для кодирования объекта
  • Затем выполните итерацию каждого объекта кода, обфусцируйте co_code каждого объекта кода следующим образом
    0 JUMP_ABSOLUTE n = 3 + len (байт-код)

    3
    ...
    ... здесь это запутанный байт-код
    ...

    n LOAD_GLOBAL? (__Pyarmor__)
    n + 3 CALL_FUNCTION 0
    n + 6 POP_TOP
    n + 7 JUMP_ABSOLUTE 0
  • Сохранить обфусцированный код объекта как .pyc или .pyo файл

Этот запутанный файл (.pyc или .pyo) может использоваться обычным интерпретатором Python, когда этот объект кода вызывается впервые

  • Первая операция - JUMP_ABSOLUTE, она перейдет к смещению n

  • При смещении n инструкция должна вызвать функцию PyCFunction. Эта функция восстановит запутанный байт-код между смещением 3 и n и поместит исходный байт-код в смещение 0. Обфусцированный код можно получить с помощью следующего кода

        char * obfucated_bytecode;
        Py_ssize_t len;
        PyFrameObject * frame = PyEval_GetFrame ();
        PyCodeObject * f_code = frame-> f_code;
        PyObject * co_code = f_code-> co_code;      
        PyBytes_AsStringAndSize (co_code, & obfucated_bytecode, & len)
    
  • После возврата этой функции последняя инструкция должна перейти к смещению 0. Теперь выполняется настоящий байт-код.

Существует инструмент Pyarmor, позволяющий запутывать сценарии Python таким способом.



1

Существует полный ответ на сокрытие исходного кода Python, который можно найти здесь .

Обсуждаются возможные методы:
- использование скомпилированного bytecode ( python -m compileall)
- создатели исполняемых файлов (или установщики, такие как PyInstaller )
- программное обеспечение как услуга (на мой взгляд, лучшее решение для сокрытия вашего кода)
- обфускаторы исходного кода python


Ссылка идет на example.com.
Дариан

@Darian спасибо, что указали на это. Я обновил ссылку.
Майк
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.