Comment protéger le code Python?


632

Je développe un logiciel en Python qui sera distribué aux clients de mon employeur. Mon employeur souhaite limiter l'utilisation du logiciel avec un fichier de licence à durée limitée.

Si nous distribuons les fichiers .py ou même les fichiers .pyc, il sera facile de (décompiler et) supprimer le code qui vérifie le fichier de licence.

Un autre aspect est que mon employeur ne veut pas que le code soit lu par nos clients, craignant que le code ne soit volé ou du moins les "idées nouvelles".

Existe-t-il un bon moyen de gérer ce problème? De préférence avec une solution standard.

Le logiciel fonctionnera sur les systèmes Linux (donc je ne pense pas que py2exe fera l'affaire).


25
py2exe stocke simplement les fichiers de code d'octets .pyc dans une archive .zip, ce n'est donc certainement pas une solution. Pourtant, cela peut être utile lorsqu'il est combiné avec un script de démarrage approprié pour le faire fonctionner sous Linux
Ber


Ceci est la réponse la plus complète à votre question: wiki.python.org/moin/Asking%20for%20Help/…
Mike

Réponses:


378

Python, étant un langage interprété compilé par code d'octet, est très difficile à verrouiller. Même si vous utilisez un exe-packager comme py2exe , la disposition de l'exécutable est bien connue et les octets-codes Python sont bien compris.

Habituellement, dans des cas comme celui-ci, vous devez faire un compromis. Dans quelle mesure est-il vraiment important de protéger le code? Y a-t-il de vrais secrets (comme une clé pour le cryptage symétrique des virements bancaires), ou êtes-vous simplement paranoïaque? Choisissez le langage qui vous permet de développer le meilleur produit le plus rapidement possible et soyez réaliste quant à la valeur de vos nouvelles idées.

Si vous décidez que vous devez vraiment appliquer la vérification de licence en toute sécurité, écrivez-la sous la forme d'une petite extension C afin que le code de vérification de licence puisse être très difficile (mais pas impossible!) À effectuer une rétro-ingénierie, et laissez la majeure partie de votre code en Python .


157
Même si le code de vérification de licence était difficile à rétroconcevoir car il était écrit en C, ne serait-il pas encore relativement facile de supprimer les appels au code de vérification de licence?
Blair Conrad

59
Oui, selon l'endroit où le contrôle de licence est effectué. S'il y a beaucoup d'appels vers le poste, il pourrait être difficile de les supprimer. Ou vous pouvez également déplacer une autre partie cruciale de l'application dans la vérification de licence afin que la suppression de l'appel à l'extension paralyse l'application.
Ned Batchelder

103
Vraiment, tout ce travail ne consiste pas à empêcher la modification, mais à augmenter sa difficulté afin qu'elle n'en vaille plus la peine. Tout peut être rétro-conçu et modifié s'il y a suffisamment d'avantages.
Ned Batchelder

11
@Blair Conrad: Pas si le code de vérification de licence masque également les fonctionnalités. Par exemplemylicensedfunction(licenseblob liblob, int foo, int bar, std::string bash)
Brian

8
J'ai en fait vu du code python commercial livré sous forme de python intégré à l'intérieur d'une bibliothèque C. Au lieu de convertir certaines parties du code en C, ils cachent tout le code Python à l'intérieur d'une couche C protectrice. Ensuite, s'ils veulent un module importable par python, ils écrivent une extension python fine au-dessus du C. L'open source est un mode de vie beaucoup plus facile.
Mike McKerns

454

"Existe-t-il un bon moyen de gérer ce problème?" Non. Rien ne peut être protégé contre l'ingénierie inverse. Même le micrologiciel des machines DVD a été rétro-conçu et la clé de cryptage AACS exposée. Et cela malgré le fait que le DMCA en fasse une infraction pénale.

Puisqu'aucune méthode technique ne peut empêcher vos clients de lire votre code, vous devez appliquer des méthodes commerciales ordinaires.

  1. Licences. Contrats. Termes et conditions. Cela fonctionne toujours même lorsque les gens peuvent lire le code. Notez que certains de vos composants basés sur Python peuvent exiger que vous payiez des frais avant de vendre des logiciels utilisant ces composants. De plus, certaines licences open source vous interdisent de cacher la source ou les origines de ce composant.

  2. Offrir une valeur significative. Si vos affaires sont si bonnes - à un prix difficile à refuser - il n'y a aucune incitation à perdre du temps et de l'argent en inversant quoi que ce soit. L'ingénierie inverse coûte cher. Rendez votre produit un peu moins cher.

  3. Offrez des mises à niveau et des améliorations qui font de toute ingénierie inverse une mauvaise idée. Lorsque la prochaine version casse leur reverse engineering, cela ne sert à rien. Cela peut être porté à des extrêmes absurdes, mais vous devriez offrir de nouvelles fonctionnalités qui rendent la prochaine version plus précieuse que la rétro-ingénierie.

  4. Offrez une personnalisation à des tarifs si attractifs qu'ils préfèrent vous payer pour construire et prendre en charge les améliorations.

  5. Utilisez une clé de licence qui expire. C'est cruel et cela vous donnera une mauvaise réputation, mais cela fait certainement cesser de fonctionner votre logiciel.

  6. Offrez-le en tant que service Web. Le SaaS n'implique aucun téléchargement pour les clients.


7
Le point 2 est encore plus important. Si c'est moins cher que la rétro-ingénierie, plus les mises à jour annuelles, personne n'essaiera et même si c'est le cas, personne ne paiera un pirate à la place du fournisseur du logiciel.
m3nda

C'est vrai. L'ingénierie inverse est réalisable mais coûteuse dans la plupart des situations. @ S.Lott, je crois que le point 6 est plus important sur la base de la question. Si le code source doit vraiment être protégé, il doit être éloigné de l'utilisateur final.
Delali

7
Question: "existe-t-il un bon moyen de protéger ma famille et moi-même d'être assassiné par des intrus dans notre sommeil?" Internet: "Non. Tout le monde peut être rejoint, et aucun logement n'est jamais à 100% impénétrable. Une famille humaine mortelle n'est pas le bon outil pour le travail."
Un algorithme simple

Le point 5 n'a pas pu être appliqué en partant du principe qu'il peut être reconstitué et fissuré.
jjmontes

313

Python n'est pas l'outil dont vous avez besoin

Vous devez utiliser le bon outil pour faire la bonne chose, et Python n'a pas été conçu pour être obscurci. C'est le contraire; tout est ouvert ou facile à révéler ou à modifier en Python car c'est la philosophie du langage.

Si vous voulez quelque chose que vous ne pouvez pas voir, recherchez un autre outil. Ce n'est pas une mauvaise chose, il est important que plusieurs outils différents existent pour différents usages.

L'obfuscation est vraiment difficile

Même les programmes compilés peuvent être rétroconçus, alors ne pensez pas que vous pouvez protéger complètement n'importe quel code. Vous pouvez analyser le PHP obscurci, briser la clé de cryptage flash, etc. Les nouvelles versions de Windows sont à chaque fois piratées.

Avoir une obligation légale est une bonne façon de procéder

Vous ne pouvez pas empêcher quelqu'un d'utiliser abusivement votre code, mais vous pouvez facilement découvrir si quelqu'un le fait. Par conséquent, il s'agit simplement d'un problème juridique occasionnel.

La protection du code est surfaite

De nos jours, les modèles commerciaux ont tendance à privilégier la vente de services plutôt que de produits. Vous ne pouvez pas copier un service, le pirater ou le voler. Peut-être qu'il est temps d'envisager de suivre le courant ...


17
Python n'est pas l'outil dont vous avez besoin. Malbolge l' est. :)
johndodo

8
Bonne réponse, mais "problème juridique occasionnel"? Vraiment? Où habitez-vous que vous avez des questions juridiques qui sont occasionnels?
Mark E. Haase

1
Je pense que si nous avons une fréquence - combien de fois le code obscurci cher est piraté - nous pourrions dire sur la praticabilité de l'utilisation de Python et du code obscurci.
sergzach

Si votre code a des fonctionnalités intéressantes, celui qui a pu en abuser le redistribuerait @Macke
Delali

1
Comment diable "découvririez-vous facilement si quelqu'un le fait"?
Make42

145

Compilez python et distribuez des binaires!

Idée sensée:

Utilisez Cython , Nuitka , Shed Skin ou quelque chose de similaire pour compiler python en code C, puis distribuez votre application en tant que bibliothèques binaires python (pyd) à la place.

De cette façon, aucun code Python (octet) n'est laissé et vous avez fait une quantité raisonnable d'obscurcissement que quiconque (c'est-à-dire votre employeur) pouvait attendre du code normal, je pense. (.NET ou Java moins sûr que ce cas, car ce bytecode n'est pas obscurci et peut être décompilé relativement facilement en source raisonnable.)

Cython devient de plus en plus compatible avec CPython, donc je pense que cela devrait fonctionner. (J'envisage en fait cela pour notre produit .. Nous construisons déjà des bibliothèques tierces en tant que pyd / dlls, donc l'expédition de notre propre code python sous forme de binaires n'est pas une étape trop importante pour nous.)

Voir cet article de blog (pas par moi) pour un tutoriel sur la façon de le faire. (thx @hithwen)

Idée folle:

Vous pourriez probablement demander à Cython de stocker les fichiers C séparément pour chaque module, puis de les concaténer tous et de les construire avec une forte inclinaison. De cette façon, votre module Python est assez monolithique et difficile à intégrer avec des outils courants.

Au-delà de la folie:

Vous pourrez peut-être créer un seul exécutable si vous pouvez lier (et optimiser) le runtime python et toutes les bibliothèques (dll) de manière statique. De cette façon, il serait certainement difficile d'intercepter les appels vers / depuis python et les bibliothèques de framework que vous utilisez. Cela ne peut pas être fait si vous utilisez du code LGPL.


Est-ce que la compilation avec cython fonctionnerait avec une application Django python 3.4, ou pourrait-elle fonctionner sans trop d'effort?
Daniel

@Daniel: Pas sûr. Je n'ai pas essayé sur Django. N'hésitez pas à poster une nouvelle question à ce sujet.
Macke


4
@mlvljr FWIW, la compilation IMHO en fichiers binaires est un bon compromis entre vendre tous vos secrets et essayer de vous protéger contre l'ingénierie inverse de classe NSA. Surtout si vous avez une grande base de code python et des raisons d'être paranoïaque. ;)
Macke

2
Le POST de hithwen n'est plus valide maintenant.
qg_java_17137

58

Je comprends que vous souhaitez que vos clients utilisent la puissance de python mais que vous ne souhaitez pas exposer le code source.

Voici mes suggestions:

(a) Écrivez les éléments critiques du code en tant que bibliothèques C ou C ++, puis utilisez SIP ou swig pour exposer les API C / C ++ à l'espace de noms Python.

(b) Utilisez cython au lieu de Python

(c) Dans (a) et (b), il devrait être possible de distribuer les bibliothèques en tant que binaire sous licence avec une interface Python.


1
Autres possibilités dans la même veine: Shed Skin code.google.com/p/shedskin et Nuitka kayhayen24x7.homelinux.org/blog/nuitka-a-python-compiler
TryPyPy

Je viens de jeter un coup d'œil sur Shed Skin comme suggéré par TyPyPy et cela semble être de très bonnes choses!
Filipe

34

Votre employeur sait-il qu'il peut "voler" les idées que d'autres personnes tirent de votre code? Je veux dire, s'ils peuvent lire votre travail, vous aussi. Peut-être que regarder comment vous pouvez profiter de la situation donnerait un meilleur retour sur investissement que de craindre combien vous pourriez perdre.

[EDIT] Réponse au commentaire de Nick:

Rien de gagné et rien de perdu. Le client a ce qu'il veut (et l'a payé depuis qu'il a fait le changement lui-même). Puisqu'il ne publie pas le changement, c'est comme si cela n'était pas arrivé à tout le monde.

Maintenant, si le client vend le logiciel, il doit modifier l'avis de droit d'auteur (ce qui est illégal, vous pouvez donc poursuivre et gagner -> cas simple).

S'ils ne modifient pas l'avis de droit d'auteur, les clients de 2e niveau remarqueront que le logiciel provient de votre original et se demanderont ce qui se passe. Il y a de fortes chances qu'ils vous contactent et vous en apprendrez plus sur la revente de votre travail.

Encore une fois, nous avons deux cas: Le client d'origine n'a vendu que quelques exemplaires. Cela signifie qu'ils n'ont pas gagné beaucoup d'argent de toute façon, alors pourquoi s'embêter. Ou ils ont vendu en volume. Cela signifie de meilleures chances pour vous d'apprendre ce qu'ils font et de faire quelque chose à ce sujet.

Mais au final, la plupart des entreprises essaient de se conformer à la loi (une fois leur réputation ruinée, il est beaucoup plus difficile de faire des affaires). Ils ne voleront donc pas votre travail mais travailleront avec vous pour l'améliorer. Donc, si vous incluez la source (avec une licence qui vous protège de la simple revente), il est probable qu'ils repousseront simplement les modifications qu'ils ont apportées, car ils s'assureront que la modification est dans la prochaine version et qu'ils n'ont pas à la maintenir . C'est gagnant-gagnant: vous obtenez des changements et ils peuvent le faire eux-mêmes s'ils en ont vraiment, désespérément besoin, même si vous ne souhaitez pas l'inclure dans la version officielle.


Que se passe-t-il s'ils publient des logiciels pour les clients et que le client les modifie en interne sans les publier à nouveau?
Nick T

@ Nick: ne change en rien la situation. Voir mes modifications.
Aaron Digulla

6
+1 pour avoir volé des idées. Pourquoi limiter votre puissance au service des clients à vos solutions internes, alors que vous pouvez voir comment les autres améliorent votre solution et améliorent en conséquence votre propre produit? "Si vous avez une pomme et j'ai une pomme et que nous échangeons ces pommes, vous et moi aurons toujours chacun une pomme. Mais si vous avez une idée et j'ai une idée et que nous échangeons ces idées, alors chacun de nous aura deux idées. "
Jordan

Et si l'un de vos clients réédite votre code ou vos idées gratuitement et anonymement? Vous ne pouvez pas dire qui l'a fait et les poursuivre en justice et parce qu'ils n'en ont pas bénéficié, vous ne le ferez pas aussi bien. Cela ruinera votre travail alors que l'un de vos clients ne paiera que le prix de base. (ne fonctionne évidemment que si vous avez plus d'un client pour votre solution)
Skandix

1
@Skandix Comment cela fonctionnerait-il exactement? Le téléchargement de votre travail sur Internet ne vous nuit pas. Cela commencerait à vous nuire si beaucoup de gens le trouvaient ET ces personnes paieraient des clients à la place. Le vol de code est un mythe. "Mes connaissances sont gratuites, mon temps coûte cher" (je ne sais pas qui a dit cela).
Aaron Digulla

34

Avez-vous regardé pyminifier ? Il réduit, obscurcit et compresse le code Python. L'exemple de code semble assez désagréable pour la rétro-ingénierie occasionnelle.

$ 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
Le bon point à ce sujet est de démoraliser quiconque essaie de décoder la fonctionnalité. Combinez cela avec Cython et des cryptes supplémentaires via des modules ou des appels Internet, et vous avez probablement un prix.
m3nda

La seule chose que ce paquet a réussi à accomplir est de tromper «l'obfuscateur» que le code est obscurci.
markroxor

cela faisait des erreurs quand j'ai essayé. Je pense qu'il a mal géré les données et ne les a pas entièrement converties.
Vicrobot

ne fonctionne pas pour le projet entier ou le moteur de modèle car il a besoin que le nom de la variable s'affiche sur le modèle
TomSawyer

Cette bibliothèque ne semble pas être maintenue et me donne des erreurs d'indentation. J'utilise Python 3.7
PV

25

Ne comptez pas sur l'obscurcissement. Comme vous l'avez correctement conclu, il offre une protection très limitée. MISE À JOUR: Voici un lien vers le papier qui inverse le code python obscurci par ingénierie dans Dropbox. L'approche - le remappage d'opcode est un bon obstacle, mais il est clair qu'il peut être vaincu.

Au lieu de cela, comme de nombreuses affiches l'ont mentionné, faites-le:

  • Ne vaut pas le temps de l'ingénierie inverse (votre logiciel est si bon qu'il est logique de payer)
  • Faites-leur signer un contrat et faites un audit de licence si possible.

Alternativement, comme le fait le kick-ass Python IDE WingIDE: Donner le code . C'est vrai, donnez le code et demandez aux gens de revenir pour les mises à niveau et le support.


1
Comme cette idée extrême. Le fait sortir de manière énorme et une part de marché énorme, alors vous avez une très grande base de clients pour le support et les extensions. J'ai également été aux prises avec cette question et toutes les réponses "licences" sont essentiellement taureau car il ne protège pas contre la copie généralisée, mais ne vous donne aucun avantage de part de marché.
Thomas Browne

Mais, les mises à niveau ne sont que des cadeaux ... alors comment factureraient-elles cela? Ne serait-ce pas simplement le support?
Make42

Concernant le modèle commercial WingIDE: le support est un service, le logiciel un produit. L'échelle des produits, pas le service. Le support n'est un bon modèle commercial que s'il n'y a pas d'autre modèle commercial - c'est-à-dire que si personne n'achèterait votre produit (pour une raison quelconque), vous donnez le produit, afin d'avoir une clientèle qui achète au moins votre service.
Make42

20

Utilisez Cython . Il compilera vos modules dans des fichiers C très performants, qui peuvent ensuite être compilés dans des bibliothèques binaires natives. C'est fondamentalement non réversible, comparé au bytecode .pyc!

J'ai écrit un article détaillé sur la façon de configurer Cython pour un projet Python, consultez-le:

Protection des sources Python avec Cython


19

La livraison de fichiers .pyc a ses problèmes - ils ne sont pas compatibles avec une autre version de python que la version de python avec laquelle ils ont été créés, ce qui signifie que vous devez savoir quelle version de python est exécutée sur les systèmes sur lesquels le produit fonctionnera. C'est un facteur très limitant.


Oui, mais pas si vous distribuez cette version exacte de Python avec votre code obscurci.
Alex

17

Dans certaines circonstances, il peut être possible de déplacer (tout ou au moins une partie clé) du logiciel vers un service Web hébergé par votre organisation.

De cette façon, les vérifications de licence peuvent être effectuées dans la sécurité de votre propre salle de serveurs.


+1 (retour à 0): il semble que la seule vraie solution au problème, en supposant qu'une telle approche soit pratique pour le cadre.
intuition

10
Gardez à l'esprit que si votre serveur Web de licences tombe en panne ou que l'accès Internet des clients est en panne, vos clients ne seront pas satisfaits qu'ils ne puissent pas gérer leur entreprise en raison de la perte d'accès aux contrôles de licences.
DevPlayer

1
@DevPlayer Il existe des solutions à cela. Vous pouvez implémenter un mécanisme de clé locale qui permet un accès temporaire lorsque le logiciel ne peut pas atteindre le serveur de licences distant.
Jeffrey

1
@Jeffrey: Cela vous ramène là où vous avez commencé - comment protéger ce code. Pour être plus sûr, vous devez mettre certaines des fonctionnalités clés sur votre propre serveur, donc le remplacer nécessiterait beaucoup d'efforts (à quel moment, pourquoi ne pas simplement lancer un concurrent open source?)
Oddthinking

14

Bien qu'il n'y ait pas de solution parfaite, les actions suivantes peuvent être effectuées:

  1. Déplacez une partie critique du code de démarrage dans une bibliothèque native.
  2. Appliquez la vérification de licence dans la bibliothèque native.

Si l'appel au code natif devait être supprimé, le programme ne démarrerait pas de toute façon. S'il n'est pas supprimé, la licence sera appliquée.

Bien que ce ne soit pas une solution multiplateforme ou pure Python, cela fonctionnera.


3
L'approche de la bibliothèque native permet à quelqu'un de forcer par programmation votre système de clés de licence beaucoup plus facilement car il peut utiliser votre propre code et API pour valider ses licences.
Tom Leys

8
Donc? Utilisez RSA pour signer votre licence et laissez-les forcer votre clé privée, disons composée de 1024 bits. C'est possible, mais cela prend beaucoup de temps ... et donc - de l'argent.
Abgan

12

Je pense qu'il existe une autre méthode pour protéger votre code Python; partie de la méthode d'obfuscation. Je crois qu'il y avait un jeu comme Mount and Blade ou quelque chose qui a changé et recompilé leur propre interprète python (l'interpréteur original qui je pense est open source) et qui vient de changer les codes OP dans la table de codes OP pour être différent de l'OP python standard codes.

Ainsi, la source python n'est pas modifiée, mais les extensions de fichier des fichiers * .pyc sont différentes et les codes op ne correspondent pas à l'interpréteur public python.exe. Si vous avez vérifié les fichiers de données de jeux, toutes les données étaient au format source Python.

Toutes sortes de trucs désagréables peuvent être faits pour jouer avec les pirates immatures de cette façon. Arrêter un tas de pirates informatiques inexpérimentés est facile. Ce sont les hackers professionnels que vous ne battrez probablement pas. Mais la plupart des entreprises ne gardent pas longtemps les hackers pro sur leur personnel (probablement parce que les choses sont piratées). Mais les pirates immatures sont partout (lus comme un personnel informatique curieux).

Vous pouvez par exemple, dans un interpréteur modifié, lui permettre de vérifier certains commentaires ou chaînes de doc dans votre source. Vous pourriez avoir des codes OP spéciaux pour de telles lignes de code. Par exemple:

L'OP 234 est pour la ligne source "# Copyright j'ai écrit ceci" ou compile cette ligne en codes op équivalents à "si Faux:" si "# Copyright" est manquant. Désactiver fondamentalement un bloc entier de code pour ce qui semble être une raison obscure.

Un cas d'utilisation où la recompilation d'un interprète modifié peut être possible est celui où vous n'avez pas écrit l'application, l'application est grande, mais vous êtes payé pour la protéger, comme lorsque vous êtes un administrateur de serveur dédié pour une application financière.

Je trouve un peu contradictoire de laisser la source ou les opcodes ouverts pour les globes oculaires, mais j'utilise SSL pour le trafic réseau. SSL n'est pas sûr à 100% non plus. Mais il est utilisé pour empêcher la plupart des yeux de le lire. Une petite précaution est raisonnable.

De plus, si suffisamment de personnes jugent que la source Python et les opcodes sont trop visibles, il est probable que quelqu'un finira par développer au moins un outil de protection simple pour cela. Donc, plus les gens demandent «comment protéger l'application Python», cela ne fait que promouvoir ce développement.


11

Le seul moyen fiable de protéger le code est de l'exécuter sur un serveur que vous contrôlez et de fournir à vos clients un client qui s'interface avec ce serveur.


10

J'ai été surpris de ne pas voir de béton armé dans aucune réponse. Peut-être parce que c'est plus récent que la question?

Cela pourrait être exactement ce dont vous avez besoin (ndlr).

Au lieu de brouiller le code, il le chiffre et le déchiffre au moment du chargement.

De la page pypi :

Protéger le flux de travail du script python

  • your_script.py import pyconcrete
  • pyconcrete accrochera le module d'importation
  • lorsque votre script est importé MODULE, le crochet d'importation pyconcrete essaiera de trouver d' MODULE.pyeabord, puis de déchiffrer MODULE.pyevia _pyconcrete.pydet d'exécuter les données déchiffrées (en tant que contenu .pyc)
  • chiffrer et déchiffrer l'enregistrement de la clé secrète dans _pyconcrete.pyd (comme DLL ou SO) la clé secrète serait masquée dans le code binaire, ne peut pas la voir directement dans la vue HEX

9

Selon qui est le client, un mécanisme de protection simple, combiné à un accord de licence raisonnable sera loin plus efficace que tout système de licence / cryptage / obscurcissement complexe.

La meilleure solution serait de vendre le code en tant que service, par exemple en hébergeant le service ou en offrant une assistance - bien que ce ne soit pas toujours pratique.

L'expédition du code sous forme de .pycfichiers empêchera votre protection d'être déjouée de quelques #secondes, mais ce n'est pas une protection anti-piratage efficace (comme s'il y avait une telle technologie), et à la fin de la journée, cela ne devrait rien faire qu'un accord de licence décent avec la société sera.

Concentrez-vous à rendre votre code aussi agréable à utiliser que possible - avoir des clients satisfaits fera gagner beaucoup plus d'argent à votre entreprise que d'empêcher un piratage théorique.


8

Une autre tentative pour rendre votre code plus difficile à voler consiste à utiliser jython puis à utiliser l' obfuscator java .

Cela devrait fonctionner assez bien car jythonc traduit le code python en java, puis java est compilé en bytecode. Donc, une fois que vous obscurcissez les classes, il sera vraiment difficile de comprendre ce qui se passe après la décompilation, sans parler de la récupération du code réel.

Le seul problème avec jython est que vous ne pouvez pas utiliser de modules python écrits en c.


6

Qu'en est-il de la signature de votre code avec des schémas de cryptage standard en hachant et en signant les fichiers importants et en le vérifiant avec les méthodes de clé publique?

De cette façon, vous pouvez émettre un fichier de licence avec une clé publique pour chaque client.

En plus, vous pouvez utiliser un obfuscateur python comme celui-ci (il suffit de le googler).


1
+1 Pour la signature; -1 pour l'obfuscateur Vous pouvez au moins empêcher la modification du code.
Ali Afshar

2
La signature ne fonctionne pas dans ce contexte. Il est toujours possible de contourner le chargeur de vérification de signature. La première chose dont vous avez besoin pour une protection logicielle utile est un mécanisme de bootstrap opaque. Pas quelque chose que Python rend facile.
ddaa

Oui, bootstrap en non-python.
Ali Afshar

Ou validez la licence non seulement au démarrage mais à plusieurs autres endroits. Peut être facilement implémenté et peut considérablement augmenter le temps de contournement.
Abgan

6

Vous devriez voir comment les gars de getdropbox.com le font pour leur logiciel client, y compris Linux. Il est assez délicat à craquer et nécessite un démontage assez créatif pour dépasser les mécanismes de protection.


8
mais le fait qu'il ait été dépassé signifiait qu'ils avaient échoué - l'essentiel est simplement de ne pas essayer, mais optez pour une protection juridique.
Chii

Y a-t-il des informations publiées sur la façon de faire passer ces mécanismes de protection?
Mitar

6

Le mieux que vous puissiez faire avec Python est d'obscurcir les choses.

  • Retirer toutes les docstrings
  • Distribuez uniquement les fichiers compilés .pyc.
  • geler
  • Obscurcissez vos constantes dans une classe / un module pour que help (config) ne montre pas tout

Vous pourrez peut-être ajouter une certaine obscurité supplémentaire en en chiffrant une partie et en la déchiffrant à la volée et en la transmettant à eval (). Mais quoi que vous fassiez, quelqu'un peut le casser.

Rien de tout cela n'empêchera un attaquant déterminé de démonter le bytecode ou de fouiller dans votre API avec de l'aide, dir, etc.


5

L'idée d'avoir une licence à durée limitée et de la vérifier dans le programme installé localement ne fonctionnera pas. Même avec une obfuscation parfaite, le contrôle de licence peut être supprimé. Cependant, si vous vérifiez la licence sur le système distant et exécutez une partie importante du programme sur votre système distant fermé, vous pourrez protéger votre adresse IP.

Empêcher les concurrents d'utiliser le code source comme le leur ou d'écrire leur version inspirée du même code, une façon de protéger consiste à ajouter des signatures à la logique de votre programme (quelques secrets pour pouvoir prouver que le code vous a été volé) et à masquer la le code source de python est donc difficile à lire et à utiliser.

Un bon obscurcissement ajoute fondamentalement la même protection à votre code que la compilation en exécutable (et en supprimant le binaire). Déterminer comment fonctionne un code complexe obscurci peut être encore plus difficile que d'écrire votre propre implémentation.

Cela n'aidera pas à empêcher le piratage de votre programme. Même avec le code de brouillage, les éléments de licence seront fissurés et le programme peut être modifié pour avoir un comportement légèrement différent (de la même manière que la compilation de code en binaire n'aide pas à la protection des programmes natifs).

En plus de l'obscurcissement des symboles, il peut être judicieux de ne pas refaire le code, ce qui rend tout encore plus confus si, par exemple, les graphiques d'appel pointent vers de nombreux endroits différents, même si en réalité ces différents endroits finissent par faire la même chose.

Signature logique à l'intérieur du code obscurci (par exemple, vous pouvez créer une table de valeurs qui sont utilisées par la logique du programme, mais également utilisées comme signature), qui peut être utilisée pour déterminer que le code provient de vous. Si quelqu'un décide d'utiliser votre module de code obscurci dans le cadre de son propre produit (même après l'avoir ressuscité pour le rendre différent), vous pouvez le montrer, ce code est volé avec votre signature secrète.


4

J'ai regardé la protection logicielle en général pour mes propres projets et la philosophie générale est qu'une protection complète est impossible. La seule chose que vous pouvez espérer obtenir est d'ajouter une protection à un niveau qui coûterait plus cher à votre client à contourner qu'à l'achat d'une autre licence.

Cela dit, je vérifiais simplement google pour obsfucation python et ne tournais pas beaucoup de choses. Dans une solution .Net, obsfucation serait une première approche de votre problème sur une plate-forme Windows, mais je ne sais pas si quelqu'un a des solutions sur Linux qui fonctionnent avec Mono.

La prochaine chose serait d'écrire votre code dans un langage compilé, ou si vous voulez vraiment aller jusqu'au bout, alors dans l'assembleur. Un exécutable dépouillé serait beaucoup plus difficile à décompiler qu'un langage interprété.

Tout se résume à des compromis. D'une part, vous avez la facilité de développement de logiciels en python, dans lequel il est également très difficile de cacher des secrets. À l'autre extrémité, vous avez un logiciel écrit en assembleur, ce qui est beaucoup plus difficile à écrire, mais il est beaucoup plus facile de cacher des secrets.

Votre patron doit choisir un point quelque part dans ce continuum qui répond à ses besoins. Et puis il doit vous donner les outils et le temps pour que vous puissiez construire ce qu'il veut. Cependant, je parie qu'il s'opposera aux coûts de développement réels contre les pertes monétaires potentielles.


4

Longue histoire courte:

  1. Chiffrez votre code source
  2. Écrivez votre propre chargeur de module python pour décrypter votre code lors de l'importation
  3. Implémenter le chargeur de modules en C / C ++
  4. Vous pouvez ajouter plus de fonctionnalités au chargeur de module, par exemple l'anti-débogueur, le contrôle de licence, la liaison d'empreintes digitales matérielles, etc.

Pour plus de détails, regardez cette réponse .

Si le sujet vous intéresse, ce projet vous aidera - pyprotect .


3

Il est possible d'avoir le code d'octet py2exe dans une ressource cryptée pour un lanceur C qui le charge et l'exécute en mémoire. Quelques idées ici et ici .

Certains ont également pensé à un programme d' auto-modification pour rendre la rétro-ingénierie coûteuse.

Vous pouvez également trouver des didacticiels pour empêcher les débogueurs , faire échouer le désassembleur, définir de faux points d'arrêt pour le débogueur et protéger votre code avec des sommes de contrôle. Recherchez ["code crypté" exécutez "en mémoire"] pour plus de liens.

Mais comme d'autres l'ont déjà dit, si votre code en vaut la peine, le reverse engineering réussira finalement.


3

Si nous nous concentrons sur les licences logicielles, je recommanderais de jeter un coup d'œil à une autre réponse Stack Overflow que j'ai écrite ici pour obtenir une inspiration de la façon dont un système de vérification de clé de licence peut être construit.

Il y a une bibliothèque open-source sur GitHub qui peut vous aider avec le bit de vérification de licence.

Vous pouvez l'installer par pip install licensingpuis ajouter le code suivant:

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")

Vous pouvez en savoir plus sur la façon dont la clé publique RSA, etc. sont configurées ici .


2

Utilisez la même manière pour protéger le fichier binaire de c / c ++, c'est-à-dire pour obscurcir chaque corps de fonction dans un fichier binaire exécutable ou de bibliothèque, insérez une instruction "jump" au début de chaque entrée de fonction, passez à une fonction spéciale pour restaurer le code obscurci. Le byte-code est un code binaire du script Python, donc

  • Compilez d'abord le script python pour coder l'objet
  • Ensuite, itérez chaque objet de code, masquez le co_code de chaque objet de code comme suit
    0 JUMP_ABSOLUTE n = 3 + len (bytecode)

    3
    ...
    ... Ici c'est du bytecode obscurci
    ...

    n LOAD_GLOBAL? (__pyarmor__)
    n + 3 CALL_FUNCTION 0
    n + 6 POP_TOP
    n + 7 JUMP_ABSOLUTE 0
  • Enregistrer l'objet de code obscurci en tant que fichier .pyc ou .pyo

Ces fichiers obscurcis (.pyc ou .pyo) peuvent être utilisés par l'interpréteur python normal, lorsque cet objet de code est appelé pour la première fois

  • Le premier op est JUMP_ABSOLUTE, il sautera pour compenser n

  • Au décalage n, l'instruction est d'appeler une fonction PyCFunction. Cette fonction restaurera les bytecodes obscurcis entre l'offset 3 et n, et mettra le code d'octet original à l'offset 0. Le code obfusqué peut être obtenu par le code suivant

        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)
    
  • Après le retour de cette fonction, la dernière instruction consiste à passer à l'offset 0. Le code réellement octet est maintenant exécuté.

Il existe un outil Pyarmor pour obscurcir les scripts python de cette façon.



1

Il y a une réponse complète sur la dissimulation du code source python, qui peut être trouvée ici .

Les techniques possibles discutées sont les suivantes:
- utiliser bytecode ( python -m compileall) compilé
- créateurs exécutables (ou installateurs comme PyInstaller )
- logiciel en tant que service (la meilleure solution pour cacher votre code à mon avis)
- obfuscateurs de code source python


Le lien va à example.com.
Darian

@Darian, merci de l'avoir signalé. J'ai mis à jour le lien.
Mike
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.