Question Comment puis-je protéger le code Python?


Je développe un logiciel Python qui sera distribué aux clients de mon employeur. Mon employeur veut 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 au moins les «idées originales».

Y a-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).


522
2017-11-04 11:57


origine


Réponses:


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

Habituellement, dans des cas comme celui-ci, vous devez faire un compromis. Quelle est l'importance 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? Choisissez la langue 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 le contrôle de licence de manière sécurisée, écrivez-le en tant que petite extension C pour que le code de vérification de licence soit extrêmement difficile (mais pas impossible!) Pour décomposer et laisser la majeure partie de votre code en Python. .


323
2017-11-04 12:00



"Y at-il un bon moyen de gérer ce problème?" Rien ne peut être protégé contre l'ingénierie inverse. Même le firmware sur les machines de DVD a été inversé et Clé de chiffrement AACS exposé. Et cela malgré le fait que le DMCA en fasse une infraction criminelle.

Comme 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 payez des frais avant de vendre un logiciel utilisant ces composants. En outre, certaines licences open-source vous interdisent de dissimuler la source ou les origines de ce composant.

  2. Offre une valeur significative. Si vos affaires sont si bonnes - à un prix difficile à refuser - il n'y a pas d'incitation à perdre du temps et de l'argent à faire marche arrière. L'ingénierie inverse est coûteuse. Rendez votre produit légèrement moins cher.

  3. Offrez des mises à niveau et des améliorations qui rendent toute ingénierie inverse une mauvaise idée. Lorsque la prochaine version brise leur ingénierie inverse, 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 l'ingénierie inverse.

  4. Offrir une personnalisation à des tarifs tellement attrayants qu'ils préfèrent vous payer pour construire et soutenir les améliorations.

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

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


417
2017-11-04 12:29



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, cherchez un autre outil. Ce n'est pas une mauvaise chose, il est important que plusieurs outils différents existent pour différents usages.

L'obscurcissement est vraiment difficile

Même les programmes compilés peuvent être désargentés, donc ne pensez pas pouvoir protéger totalement le code. Vous pouvez analyser PHP masqué, briser la clé de cryptage flash, etc. Les versions les plus récentes de Windows sont fissurées à chaque fois.

Avoir une exigence légale est un bon moyen d'aller

Vous ne pouvez pas empêcher quelqu'un d'abuser de votre code, mais vous pouvez facilement découvrir si quelqu'un le fait. Par conséquent, c'est juste un problème juridique occasionnel.

La protection du code est surfaite

De nos jours, les modèles commerciaux tendent à vendre des services plutôt que des produits. Vous ne pouvez pas copier un service, pirater ou le voler. Peut-être qu'il est temps d'envisager d'aller de l'avant avec le flux ...


301
2017-11-04 13:03



Compilez python et distribuez les binaires!

Idée sensible: 

Utilisation Cython, Nuitka, Peau de hangar ou quelque chose de similaire à compiler python en code C, puis distribuer 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 toute quantité raisonnable d'obscurification que quelqu'un (c'est-à-dire votre employeur) pouvait attendre du code ordinaire, je pense. (.NET ou Java moins sûr que ce cas, car ce bytecode n'est pas obscurci et peut être facilement décompilé en source raisonnable.)

Cython devient de plus en plus compatible avec CPython, donc je pense que cela devrait fonctionner. (Je suis en train de considérer cela pour notre produit. Nous construisons déjà des librairies tierces comme pyd / dll, donc l'envoi de notre propre code python en tant que binaires n'est pas une étape trop importante pour nous.)

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

Idée folle:

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

Au-delà de fou:

Vous pourriez être capable de construire un seul exécutable si vous pouvez lier (et optimiser avec) le runtime python et toutes les bibliothèques (dlls) de façon statique. De cette façon, il sera certainement difficile d'intercepter les appels de / vers python et les bibliothèques de framework que vous utiliserez. Cela ne peut pas être fait si vous utilisez le code LGPL.


121
2017-09-08 11:14



Je comprends que vous voulez que vos clients utilisent la puissance de python mais ne veulent 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 siroter ou lampée pour exposer les API C / C ++ à l'espace de noms Python.

(b) Utilisation Cython au lieu de Python

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


56
2017-11-06 07:41



Votre employeur est-il conscient qu'il peut "voler" des idées que d'autres personnes tirent de votre code? Je veux dire, s'ils peuvent lire votre travail, vous pouvez aussi le leur. Peut-être que regarder comment vous pouvez bénéficier de la situation donnerait un meilleur rendement de votre investissement que de craindre combien vous pourriez perdre.

[EDIT] Réponse au commentaire de Nick:

Rien n'a gagné et rien perdu. Le client a ce qu'il veut (et a payé pour cela puisqu'il a fait le changement lui-même). Comme il ne libère pas le changement, c'est comme si cela n'avait pas été le cas pour tout le monde.

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

S'ils ne modifient pas l'avis de droit d'auteur, les clients de deuxième niveau remarqueront que le logiciel vient de chez vous et se demandent ce qui se passe. Il y a de fortes chances qu'ils vous contactent pour que vous puissiez en apprendre davantage sur la revente de votre travail.

Encore une fois, nous avons deux cas: Le client d'origine vendu à seulement quelques exemplaires. Cela signifie qu'ils n'ont pas fait 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 à la fin, 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). Donc, ils ne voleront 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 y a de fortes chances qu'ils repoussent tout simplement les changements qu'ils ont faits puisque cela permettra de s'assurer que le changement est dans la prochaine version. . C'est gagnant-gagnant: vous obtenez des changements et ils peuvent faire le changement eux-mêmes s'ils en ont désespérément besoin, même si vous ne voulez pas l'inclure dans la version officielle.


32
2017-11-04 12:27



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 a inversé le code python obfusqué dans Dropbox. L'approche - remappage des opcode est une bonne barrière, mais il est clair qu'elle peut être vaincue.

Au lieu de cela, comme beaucoup d'affiches l'ont mentionné:

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

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


24
2017-11-04 18:53



Avez-vous regardé pyminifier? Il Minify, obfuscate et compresse le code Python. L'exemple de code est plutôt méchant pour le reverse engineering.

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

21
2018-05-08 10:21