¿Cómo protejo el código Python?

632

Estoy desarrollando un software en Python que se distribuirá a los clientes de mi empleador. Mi empleador quiere limitar el uso del software con un archivo de licencia con restricción de tiempo.

Si distribuimos los archivos .py o incluso los archivos .pyc, será fácil (descompilar y) eliminar el código que verifica el archivo de licencia.

Otro aspecto es que mi empleador no quiere que nuestros clientes lean el código, por temor a que el código pueda ser robado o al menos las "ideas nuevas".

¿Hay una buena manera de manejar este problema? Preferiblemente con una solución lista para usar.

El software se ejecutará en sistemas Linux (así que no creo que py2exe haga el truco).

Jordfräs
fuente
25
py2exe simplemente almacena los archivos de código de bytes .pyc en un archivo .zip, por lo que definitivamente no es una solución. Aún así, eso puede ser útil cuando se combina con un script de interrupción adecuado para que se ejecute en Linux
Ber
Esta es la respuesta más completa a su pregunta: wiki.python.org/moin/Asking%20for%20Help/…
Mike

Respuestas:

378

Python, al ser un lenguaje interpretado compilado por código de bytes, es muy difícil de bloquear. Incluso si utiliza un exe-packager como py2exe , el diseño del ejecutable es bien conocido, y los códigos de bytes de Python se entienden bien.

Por lo general, en casos como este, debe hacer una compensación. ¿Qué tan importante es realmente proteger el código? ¿Hay secretos reales allí (como una clave para el cifrado simétrico de transferencias bancarias) o simplemente estás siendo paranoico? Elija el lenguaje que le permita desarrollar el mejor producto más rápido y sea realista sobre lo valiosas que son sus nuevas ideas.

Si decide que realmente necesita aplicar la verificación de licencia de forma segura, escríbala como una pequeña extensión C para que el código de verificación de licencia pueda ser muy difícil (¡pero no imposible!) Para realizar ingeniería inversa y dejar la mayor parte de su código en Python .

Ned Batchelder
fuente
157
Incluso si el código de verificación de licencia fuera difícil de aplicar ingeniería inversa porque está escrito en C, ¿no sería relativamente fácil eliminar las llamadas al código de verificación de licencia?
Blair Conrad el
59
Sí, dependiendo de dónde se realice la verificación de la licencia. Si hay muchas llamadas a la extensión, podría ser difícil de erradicar. O también puede mover otra parte crucial de la aplicación a la verificación de licencia, de modo que eliminar la llamada a la extensión paralice la aplicación.
Ned Batchelder
103
Realmente, todo este trabajo no se trata de prevenir la modificación, sino de aumentar su dificultad para que ya no valga la pena. Cualquier cosa puede ser modificada y modificada si hay suficientes beneficios.
Ned Batchelder
11
@Blair Conrad: no si el código de verificación de licencia también oculta la funcionalidad. Por ejemplomylicensedfunction(licenseblob liblob, int foo, int bar, std::string bash)
Brian el
8
De hecho, he visto el código comercial de Python enviado como Python incrustado dentro de una biblioteca C. En lugar de convertir algunas partes del código a C, ocultan todo el código de Python dentro de una capa protectora de C. Luego, si quieren un módulo importable por Python, escriben una extensión delgada de Python en la parte superior de C. El código abierto es una forma de vida mucho más fácil.
Mike McKerns
454

"¿Hay una buena manera de manejar este problema?" No. Nada puede protegerse contra la ingeniería inversa. Incluso el firmware en las máquinas de DVD ha sido modificado y la clave de cifrado AACS expuesta. Y eso a pesar de que la DMCA lo convirtió en un delito penal.

Como ningún método técnico puede impedir que sus clientes lean su código, debe aplicar métodos comerciales comunes.

  1. Licencias Contratos Términos y Condiciones. Esto todavía funciona incluso cuando las personas pueden leer el código. Tenga en cuenta que algunos de sus componentes basados ​​en Python pueden requerir que pague tarifas antes de vender el software que usa esos componentes. Además, algunas licencias de código abierto le prohíben ocultar el origen o los orígenes de ese componente.

  2. Ofrecer un valor significativo. Si sus cosas son tan buenas, a un precio difícil de rechazar, no hay incentivo para perder tiempo y dinero en ingeniería inversa. La ingeniería inversa es costosa. Haga su producto un poco menos costoso.

  3. Ofrezca actualizaciones y mejoras que hagan que cualquier ingeniería inversa sea una mala idea. Cuando el próximo lanzamiento rompa su ingeniería inversa, no tiene sentido. Esto puede llevarse a extremos absurdos, pero debe ofrecer nuevas características que hagan que la próxima versión sea más valiosa que la ingeniería inversa.

  4. Ofrezca personalización a precios tan atractivos que preferirían pagarle a usted por construir y admitir las mejoras.

  5. Use una clave de licencia que caduque. Esto es cruel y le dará una mala reputación, pero ciertamente hace que su software deje de funcionar.

  6. Ofrézcalo como un servicio web. SaaS no implica descargas a los clientes.

S.Lott
fuente
77
El punto 2 es aún más importante. Si es más barato comprar que la ingeniería inversa, más las actualizaciones anuales, nadie lo intentará e incluso si lo hace, nadie pagará a un pirata informático en lugar del proveedor del software.
m3nda
Es verdad. La ingeniería inversa es factible pero costosa en la mayoría de las situaciones. @ S.Lott, creo que el punto 6 tiene más importancia en función de la pregunta. Si el código fuente realmente necesita protección, entonces debe estar alejado del usuario final.
Delali
77
Pregunta: "¿hay una buena manera de proteger a mi familia y a mí de ser asesinados por intrusos mientras dormimos?" Internet: "No. Se puede llegar a cualquiera, y ninguna vivienda es 100% impenetrable. Una familia humana mortal es la herramienta equivocada para el trabajo".
Un algoritmo simple
El punto 5 no puede aplicarse con el mismo supuesto de que puede ser modificado y agrietado.
jjmontes
313

Python no es la herramienta que necesitas

Debe usar la herramienta correcta para hacer lo correcto, y Python no fue diseñado para ofuscarse. Es lo contrario; todo es abierto o fácil de revelar o modificar en Python porque esa es la filosofía del lenguaje.

Si quieres algo que no puedes ver, busca otra herramienta. Esto no es malo, es importante que existan varias herramientas diferentes para diferentes usos.

La ofuscación es realmente difícil

Incluso los programas compilados pueden tener ingeniería inversa, así que no piense que puede proteger completamente cualquier código. Puede analizar PHP ofuscado, romper la clave de cifrado flash, etc. Las versiones más nuevas de Windows se descifran cada vez.

Tener un requisito legal es un buen camino a seguir

No puede evitar que alguien haga un mal uso de su código, pero puede descubrir fácilmente si alguien lo hace. Por lo tanto, es solo un problema legal casual.

La protección del código está sobrevalorada

Hoy en día, los modelos de negocio tienden a vender servicios en lugar de productos. No puede copiar un servicio, piratearlo ni robarlo. Tal vez es hora de considerar seguir la corriente ...

e-satis
fuente
17
Python no es la herramienta que necesitas. Malbolge es. :)
johndodo
8
Buena respuesta, pero "problema legal casual"? De Verdad? ¿Dónde vive usted que usted tiene cualquier problemas legales que son casuales?
Mark E. Haase
1
Creo que si tenemos una frecuencia, con qué frecuencia se piratea el código ofuscado costoso, podríamos decir sobre la posibilidad de usar Python y el código ofuscado.
sergzach
Si su código tiene características interesantes, el que pudo usarlo incorrectamente lo redistribuiría @Macke
Delali
1
¿Cómo en el mundo "descubrirías fácilmente si alguien lo hace"?
Make42
145

¡Compila python y distribuye binarios!

Idea sensata:

Use Cython , Nuitka , Shed Skin o algo similar para compilar python en código C, luego distribuya su aplicación como bibliotecas binarias python (pyd).

De esa manera, no queda ningún código de Python (byte) y creo que ha realizado cualquier cantidad razonable de ocultación que cualquiera (es decir, su empleador) podría esperar del Código normal, creo. (.NET o Java son menos seguros que este caso, ya que ese bytecode no se ofusca y se puede descompilar con relativa facilidad en una fuente razonable).

Cython se está volviendo cada vez más compatible con CPython, así que creo que debería funcionar. (De hecho, estoy considerando esto para nuestro producto. Ya estamos construyendo algunas librerías de terceros como pyd / dlls, por lo que enviar nuestro propio código de Python como binarios no es un paso demasiado grande para nosotros).

Vea esta publicación de blog (no por mí) para obtener un tutorial sobre cómo hacerlo. (gracias @hithwen)

Idea loca:

Probablemente podría hacer que Cython almacene los archivos C por separado para cada módulo, luego concatene todos y compílelos con una gran línea. De esa manera, su módulo Python es bastante monolítico y difícil de usar con herramientas comunes.

Más allá de locos:

Es posible que pueda crear un solo ejecutable si puede vincular (y optimizar con) el tiempo de ejecución de Python y todas las bibliotecas (dlls) estáticamente. De esa manera, seguramente sería difícil interceptar llamadas a / desde python y cualquier biblioteca de framework que use. Sin embargo, esto no se puede hacer si está utilizando el código LGPL.

Macke
fuente
¿La compilación con cython funcionaría con una aplicación Python 3.4 Django, o podría funcionar sin una gran cantidad de esfuerzo?
Daniel
@Daniel: No estoy seguro. No lo he probado en Django. Siéntase libre de publicar una nueva pregunta al respecto.
Macke
44
@mlvljr FWIW, en mi humilde opinión, compilar en binarios es una buena compensación entre vender todos tus secretos y tratar de protegerte contra la ingeniería inversa de clase NSA. Esp si tienes una gran base de código de python y razones para ser paranoico. ;)
Macke
2
La POST de hithwen no es válida ahora.
qg_java_17137
58

Entiendo que desea que sus clientes utilicen el poder de Python, pero no desea exponer el código fuente.

Aquí están mis sugerencias:

(a) Escriba las partes críticas del código como bibliotecas C o C ++ y luego use SIP o swig para exponer las API C / C ++ al espacio de nombres Python.

(b) Use cython en lugar de Python

(c) En ambos (a) y (b), debería ser posible distribuir las bibliotecas como binarios con licencia con una interfaz Python.

Bhadra
fuente
1
Otras posibilidades en la misma línea: Shed Skin code.google.com/p/shedskin y Nuitka kayhayen24x7.homelinux.org/blog/nuitka-a-python-compiler
TryPyPy
¡Acabo de echar un vistazo a Shed Skin como lo sugirió TyPyPy y parece ser algo realmente bueno!
Filipe
34

¿Sabe su empleador que puede "robar" cualquier idea que otras personas obtengan de su código? Quiero decir, si ellos pueden leer tu trabajo, tú también puedes leer el suyo. Tal vez ver cómo puede beneficiarse de la situación generaría un mejor retorno de su inversión que temer cuánto podría perder.

[EDITAR] Respuesta al comentario de Nick:

Nada ganado y nada perdido. El cliente tiene lo que quiere (y lo pagó desde que él mismo hizo el cambio). Como no publica el cambio, es como si no hubiera sucedido para todos los demás.

Ahora, si el cliente vende el software, tiene que cambiar el aviso de copyright (que es ilegal, por lo que puede demandar y ganará -> caso simple).

Si no cambian el aviso de derechos de autor, los clientes de segundo nivel notarán que el software proviene de usted original y se preguntarán qué está pasando. Lo más probable es que se pongan en contacto con usted, por lo que aprenderá sobre la reventa de su trabajo.

Nuevamente tenemos dos casos: el cliente original vendió solo unas pocas copias. Eso significa que no hicieron mucho dinero de todos modos, entonces, ¿por qué molestarse? O se vendieron en volumen. Eso significa mejores oportunidades para que usted aprenda sobre lo que hacen y hagan algo al respecto.

Pero al final, la mayoría de las empresas intentan cumplir con la ley (una vez que se arruina su reputación, es mucho más difícil hacer negocios). Por lo tanto, no le robarán su trabajo, sino que trabajarán con usted para mejorarlo. Entonces, si incluye la fuente (con una licencia que lo protege de la simple reventa), es probable que simplemente rechacen los cambios que hicieron, ya que eso garantizará que el cambio esté en la próxima versión y no tengan que mantenerlo . Eso es ganar-ganar: obtienes cambios y ellos pueden hacer el cambio ellos mismos si realmente lo necesitan desesperadamente, incluso si no estás dispuesto a incluirlo en el lanzamiento oficial.

Aaron Digulla
fuente
¿Qué sucede si lanzan software a los clientes y el cliente lo modifica internamente sin volver a lanzarlo?
Nick T
@ Nick: No cambia la situación de ninguna manera. Mira mis ediciones.
Aaron Digulla
66
+1 por robar ideas. ¿Por qué limitar su poder de servicio al cliente a sus soluciones internas, cuando puede ver cómo otros mejoran su solución y, en consecuencia, mejoran su propio producto? "Si tienes una manzana y yo tengo una manzana e intercambiamos estas manzanas, tú y yo todavía tendremos una manzana. Pero si tienes una idea y yo tengo una idea e intercambiamos estas ideas, entonces cada uno de nosotros tendrá dos ideas ".
Jordania
¿Qué sucede si uno de sus clientes vuelve a publicar su código o las ideas de forma gratuita y anónima? No se puede saber quién lo hizo y demandarlos, y como no se beneficiaron, tampoco lo hará. Esto arruinará su trabajo mientras uno de sus clientes solo pagó el precio básico por él. (obviamente solo funciona si tiene más de un cliente para su solución)
Skandix
1
@Skandix ¿Cómo funcionaría eso exactamente? Cargar su trabajo en Internet no le hace daño. Comenzaría a hacerte daño si mucha gente lo encontrara Y esas personas estarían pagando a los clientes en su lugar. El robo de código es un mito. "Mi conocimiento es gratis, mi tiempo es caro" (no estoy seguro de quién dijo eso).
Aaron Digulla
34

¿Has echado un vistazo a pyminifier ? Hace Minify, ofusca y comprime el código Python. El código de ejemplo parece bastante desagradable para la ingeniería inversa informal.

$ 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)
Lmwangi
fuente
66
Lo bueno de esto es desmoralizar a cualquiera que intente decodificar la funcionalidad. Combine eso con Cython y algunas criptas adicionales a través de módulos o llamadas por Internet, y probablemente obtendrá el premio.
m3nda
Lo único que este paquete logró lograr es engañar al 'ofuscador' de que el código está ofuscado.
markroxor
esto estaba cometiendo errores cuando lo intenté. Creo que manejó mal los datos y no los convirtió completamente.
Vicrobot
no funciona para todo el proyecto o el motor de plantillas, ya que necesita un nombre de variable para mostrar en la plantilla
TomSawyer
Esta biblioteca no parece mantenerse y me da errores de sangría. Estoy usando Python 3.7
PV
25

No confíe en la ofuscación. Como ha concluido correctamente, ofrece una protección muy limitada. ACTUALIZACIÓN: Aquí hay un enlace al documento que invierte el código de Python ofuscado en Dropbox. El enfoque: la reasignación de opcode es una buena barrera, pero claramente puede ser derrotada.

En cambio, como muchos carteles han mencionado, hazlo:

  • No vale la pena el tiempo de ingeniería inversa (su software es tan bueno, tiene sentido pagar)
  • Haz que firmen un contrato y hagan una auditoría de licencia si es posible.

Alternativamente, como lo hace el increíble IDE WingIDE de Python: el código . Así es, regale el código y haga que la gente regrese para actualizaciones y soporte.

Konrads
fuente
1
Me gusta esta idea extrema. Lo obtiene de una manera enorme y una participación de mercado masiva, entonces tiene una base de clientes muy grande para soporte y complementos. También he estado lidiando con esta pregunta y todas las respuestas de "licencia" son básicamente falsas porque no protege contra la copia generalizada, pero no le da ninguna ventaja de participación en el mercado.
Thomas Browne
Pero, las actualizaciones también son simplemente obsequios ... entonces, ¿cómo cobrarían por eso? ¿No sería solo el soporte?
Make42
Con respecto al modelo de negocio WingIDE: el soporte es un servicio, el software es un producto. Escala de productos, servicio no. El soporte es solo un buen modelo de negocio si no hay otro modelo de negocio, es decir, si nadie compraría su producto (por alguna razón), usted regala el producto, de modo que tenga una base de clientes que al menos compre su servicio.
Make42
20

Utiliza Cython . Compilará sus módulos en archivos C de alto rendimiento, que luego se pueden compilar en bibliotecas binarias nativas. ¡Esto es básicamente irreversible, en comparación con el bytecode .pyc!

He escrito un artículo detallado sobre cómo configurar Cython para un proyecto de Python, échale un vistazo:

Protección de fuentes de Python con Cython

Vitaly Gordon
fuente
19

El envío de archivos .pyc tiene sus problemas: no son compatibles con ninguna otra versión de Python que no sea la versión con la que se crearon, lo que significa que debe saber qué versión de Python se está ejecutando en los sistemas en los que se ejecutará el producto. Ese es un factor muy limitante.

Erik Forsberg
fuente
Sí, pero no si distribuye esa versión exacta de Python con su código ofuscado.
Alex
17

En algunas circunstancias, es posible mover (todo, o al menos una parte clave) del software a un servicio web que aloja su organización.

De esa manera, las verificaciones de licencia se pueden realizar en la seguridad de su propia sala de servidores.

Pensamiento extraño
fuente
+1 (volver a 0): parece la única solución verdadera al problema, suponiendo que este enfoque sea práctico para el entorno.
intuido
10
Tenga en cuenta que si su servidor web de licencias deja de funcionar o si el acceso a Internet de los clientes no funciona, su cliente no estará contento de no poder administrar su negocio debido a la pérdida de acceso a las verificaciones de licencias.
DevPlayer
1
@DevPlayer Hay soluciones para esto. Podría implementar un mecanismo de clave local que permita el acceso temporal cuando el software no pueda llegar al servidor de licencias remoto.
Jeffrey
1
@Jeffrey: Eso te lleva de vuelta a donde empezaste: cómo proteger ese código. Para ser más seguro, es necesario poner un poco de la funcionalidad clave en su propio servidor, por lo que implicaría la sustitución sustancialmente esfuerzo (y en ese momento, ¿por qué no iniciar un competidor de código abierto?)
Oddthinking
14

Aunque no hay una solución perfecta, se puede hacer lo siguiente:

  1. Mueva alguna pieza crítica de código de inicio a una biblioteca nativa.
  2. Haga cumplir la verificación de licencia en la biblioteca nativa.

Si se eliminara la llamada al código nativo, el programa no se iniciaría de todos modos. Si no se elimina, se aplicará la licencia.

Aunque no se trata de una solución multiplataforma o de Python puro, funcionará.

Smi
fuente
3
El enfoque de la biblioteca nativa hace que sea mucho más fácil para alguien forzar mediante programación la fuerza bruta de su sistema de clave de licencia, ya que puede usar su propio código y API para validar sus licencias.
Tom Leys el
8
¿Entonces? Use RSA para firmar su licencia y deje que fuercen su clave privada por fuerza bruta, digamos que consiste en 1024 bits. Es posible, pero lleva mucho tiempo ... y por lo tanto, dinero.
Abgan
12

Creo que hay un método más para proteger su código Python; parte del método de ofuscación. Creo que hubo un juego como Mount and Blade o algo que cambió y recompiló su propio intérprete de Python (el intérprete original, que creo que es de código abierto) y simplemente cambió los códigos OP en la tabla de códigos OP para ser diferentes al OP Python estándar códigos

Por lo tanto, la fuente de Python no se modifica, pero las extensiones de archivo de los archivos * .pyc son diferentes y los códigos operativos no coinciden con el intérprete público python.exe. Si revisó los archivos de datos de los juegos, todos los datos estaban en formato fuente Python.

Se pueden hacer todo tipo de trucos desagradables para meterse con hackers inmaduros de esta manera. Detener a un grupo de hackers sin experiencia es fácil. Son los hackers profesionales los que probablemente no vencerás. Pero imagino que la mayoría de las empresas no mantienen a los hackers profesionales en el personal durante mucho tiempo (probablemente porque las cosas se piratean). Pero los hackers inmaduros están por todas partes (léase como personal de TI curioso).

Podría, por ejemplo, en un intérprete modificado, permitirle verificar ciertos comentarios o cadenas de documentos en su fuente. Podría tener códigos OP especiales para tales líneas de código. Por ejemplo:

El OP 234 es para la línea de origen "# Copyright He escrito esto" o compile esa línea en códigos operativos que sean equivalentes a "if False:" if "# # Copyright" missing. Básicamente, deshabilitar todo un bloque de código por lo que parece ser una razón oscura.

Un caso de uso en el que puede ser posible recompilar un intérprete modificado es donde no escribió la aplicación, la aplicación es grande, pero se le paga para protegerla, como cuando es un administrador de servidor dedicado para una aplicación financiera.

Me resulta un poco contradictorio dejar la fuente o los códigos de operación abiertos para los globos oculares, pero usar SSL para el tráfico de red. SSL tampoco es 100% seguro. Pero se usa para evitar que la mayoría de los ojos lo lean. Una pequeña precaución es sensata.

Además, si suficientes personas consideran que la fuente de Python y los códigos de operación son demasiado visibles, es probable que alguien finalmente desarrolle al menos una herramienta de protección simple para ello. Por lo tanto, cada vez más personas que preguntan "cómo proteger la aplicación Python" solo promueven ese desarrollo.

DevPlayer
fuente
11

La única forma confiable de proteger el código es ejecutarlo en un servidor que controle y proporcionar a sus clientes un cliente que interactúe con ese servidor.

Alex Coventry
fuente
10

Me sorprendió no ver pyconcrete en ninguna respuesta. ¿Quizás porque es más nuevo que la pregunta?

Podría ser exactamente lo que necesita (ed).

En lugar de ofuscar el código, lo cifra y descifra en el momento de la carga.

Desde la página de pypi :

Proteger el flujo de trabajo de script de Python

  • your_script.py import pyconcrete
  • pyconcrete enganchará el módulo de importación
  • cuando su script importa MODULE, el enlace de importación pyconcrete intentará encontrar MODULE.pyeprimero y luego descifrar MODULE.pyemediante _pyconcrete.pydy ejecutar datos descifrados (como contenido .pyc)
  • cifrar y descifrar el registro de clave secreta _pyconcrete.pyd (como DLL o SO) la clave secreta estaría oculta en código binario, no se puede ver directamente en la vista HEX
mvallebr
fuente
9

Dependiendo de quién sea el cliente, un simple mecanismo de protección, combinado con un acuerdo de licencia sensato, estará lejos más efectivo que cualquier sistema complejo de licencia / cifrado / ofuscación.

La mejor solución sería vender el código como un servicio, por ejemplo, alojando el servicio u ofreciendo soporte, aunque eso no siempre es práctico.

Enviar el código como .pycarchivos evitará que su protección se vea frustrada por unos pocos #segundos, pero no es una protección efectiva contra la piratería (como si hubiera tal tecnología), y al final del día, no debería lograr nada que acuerdo de licencia decente con la empresa lo hará.

Concéntrese en hacer que su código sea lo más agradable posible de usar: tener clientes satisfechos hará que su empresa gane mucho más dinero que evitar una piratería teórica.

dbr
fuente
8

Otro intento de hacer que su código sea más difícil de robar es usar jython y luego usar java ofuscador .

Esto debería funcionar bastante bien ya que jythonc traduce el código de Python a Java y luego Java se compila a bytecode. Entonces, si ofuscas las clases, será muy difícil entender lo que está sucediendo después de la descompilación, sin mencionar la recuperación del código real.

El único problema con jython es que no puedes usar módulos de python escritos en c.

Piotr Czapla
fuente
6

¿Qué pasa con la firma de su código con esquemas de cifrado estándar mediante el hash y firmando archivos importantes y verificándolo con métodos de clave pública?

De esta forma, puede emitir un archivo de licencia con una clave pública para cada cliente.

Además, puede usar un ofuscador de pitón como este (simplemente busqué en Google).

Peter Parker
fuente
1
+1 para la firma; -1 para el ofuscador Al menos puede evitar que se cambie el código.
Ali Afshar
2
La firma no funciona en este contexto. Siempre es posible omitir el cargador de verificación de firmas. Lo primero que necesita para una protección útil del software es un mecanismo de arranque opaco. No es algo que Python haga fácil.
ddaa
Sí, bootstrap en no Python.
Ali Afshar
O valide la licencia no solo en el inicio sino en varios otros lugares. Se puede implementar fácilmente y puede aumentar severamente el tiempo de derivación.
Abgan
6

Debes echar un vistazo a cómo los chicos de getdropbox.com lo hacen por su software cliente, incluido Linux. Es bastante difícil de descifrar y requiere un desmontaje bastante creativo para superar los mecanismos de protección.

fwzgekg
fuente
8
pero el hecho de que se haya superado significa que fracasaron: la conclusión es simplemente no intentarlo, sino buscar protección legal.
Chii
¿Hay alguna información publicada sobre cómo pasar estos mecanismos de protección?
Mitar
6

Lo mejor que puedes hacer con Python es ocultar las cosas.

  • Retirar todas las cadenas de documentos
  • Distribuya solo los archivos compilados .pyc.
  • congelarlo
  • Oculte sus constantes dentro de una clase / módulo para que help (config) no muestre todo

Es posible que pueda agregar algo de oscuridad adicional encriptando parte de él y descifrándolo sobre la marcha y pasándolo a eval (). Pero no importa lo que hagas, alguien puede romperlo.

Nada de esto impedirá que un atacante determinado desarme el código de bytes o explore su API con ayuda, dir, etc.

Brian C. Lane
fuente
5

La idea de tener una licencia de tiempo restringido y verificarla en el programa instalado localmente no funcionará. Incluso con una ofuscación perfecta, se puede eliminar la verificación de licencia. Sin embargo, si verifica la licencia en el sistema remoto y ejecuta una parte importante del programa en su sistema remoto cerrado, podrá proteger su IP.

Para evitar que los competidores usen el código fuente como propio o escriban su versión inspirada del mismo código, una forma de proteger es agregar firmas a la lógica de su programa (algunos secretos para poder probar que le robaron el código) y ofuscar el código fuente de Python, por lo tanto, es difícil de leer y utilizar.

La buena ofuscación agrega básicamente la misma protección a su código, que compilarlo en ejecutable (y eliminar binario). Descubrir cómo funciona el código complejo ofuscado podría ser aún más difícil que escribir su propia implementación.

Esto no ayudará a evitar la piratería de su programa. Incluso con el código de ofuscación, las cosas de la licencia se descifrarán y el programa puede modificarse para tener un comportamiento ligeramente diferente (de la misma manera que compilar código en binario no ayuda a la protección de los programas nativos).

Además de la ofuscación de símbolos, puede ser una buena idea no refactorizar el código, lo que hace que todo sea aún más confuso si, por ejemplo, los gráficos de llamadas apuntan a muchos lugares diferentes, incluso si en realidad esos diferentes lugares eventualmente hacen lo mismo.

Firma lógica dentro del código ofuscado (por ejemplo, puede crear una tabla de valores que son usados ​​por la lógica del programa, pero también usados ​​como firma), que pueden usarse para determinar que el código se originó en usted. Si alguien decide usar su módulo de código ofuscado como parte de su propio producto (incluso después de volver a ofuscarlo para que parezca diferente), puede mostrar que ese código es robado con su firma secreta.

Mikael Lepistö
fuente
4

He analizado la protección de software en general para mis propios proyectos y la filosofía general es que la protección completa es imposible. Lo único que puede esperar lograr es agregar protección a un nivel que le cueste más a su cliente eludir que comprar otra licencia.

Con eso dicho, solo estaba buscando en google para detectar la fuga de python y no aparecía mucho. En una solución .Net, el oscurecimiento sería un primer enfoque para su problema en una plataforma Windows, pero no estoy seguro de si alguien tiene soluciones en Linux que funcionen con Mono.

Lo siguiente sería escribir su código en un lenguaje compilado, o si realmente quiere ir hasta el final, entonces en ensamblador. Un ejecutable eliminado sería mucho más difícil de descompilar que un lenguaje interpretado.

Todo se reduce a compensaciones. Por un lado, tiene facilidad de desarrollo de software en python, en el que también es muy difícil ocultar secretos. Por otro lado, tiene un software escrito en ensamblador que es mucho más difícil de escribir, pero es mucho más fácil ocultar secretos.

Su jefe tiene que elegir un punto en algún lugar de ese continuo que respalde sus requisitos. Y luego tiene que darte las herramientas y el tiempo para que puedas construir lo que quiere. Sin embargo, mi apuesta es que se opondrá a los costos de desarrollo reales frente a las posibles pérdidas monetarias.

Peter M
fuente
4

Larga historia corta:

  1. Cifra tu código fuente
  2. Escriba su propio cargador de módulo de Python para descifrar su código al importar
  3. Implemente el cargador de módulos en C / C ++
  4. Puede agregar más funciones al cargador de módulos, por ejemplo, anti-depurador, control de licencias, encuadernación de huellas digitales de hardware, etc.

Para más detalles, mira esta respuesta .

Si está interesado en el tema, este proyecto lo ayudará: pyprotect .

lambda11
fuente
3

Es posible tener el código de bytes py2exe en un recurso encriptado para un iniciador de C que lo carga y ejecuta en la memoria. Algunas ideas aquí y aquí. .

Algunos también han pensado en un programa auto modificable para hacer que la ingeniería inversa sea costosa.

También puede encontrar tutoriales para prevenir depuradores , hacer que el desensamblador falle, establecer puntos de interrupción falsos del depurador y proteger su código con sumas de verificación. Busque ["código encriptado" ejecutar "en memoria"] para obtener más enlaces.

Pero como ya dijeron otros, si su código lo vale, los ingenieros inversos tendrán éxito al final.

lalebarde
fuente
3

Si nos centramos en las licencias de software, recomendaría echar un vistazo a otra respuesta de desbordamiento de pila que escribí aquí para obtener alguna inspiración de cómo se puede construir un sistema de verificación de clave de licencia.

Hay una biblioteca de código abierto en GitHub que puede ayudarlo con el bit de verificación de licencia.

Puede instalarlo pip install licensingy luego agregar el siguiente código:

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

Puede leer más sobre la forma en que la clave pública RSA, etc.está configurada aquí .

Artem
fuente
2

Use la misma manera para proteger el archivo binario de c / c ++, es decir, ofusque cada cuerpo de función en el archivo binario ejecutable o de la biblioteca, inserte una instrucción "jump" al comienzo de cada entrada de función, salte a una función especial para restaurar el código ofuscado. El código de bytes es el código binario del script de Python, por lo que

  • Primero compila el script de Python para codificar el objeto
  • Luego itere cada objeto de código, ofusque el co_código de cada objeto de código de la siguiente manera
    0 JUMP_ABSOLUTE n = 3 + len (código de bytes)

    3
    ...
    ... Aquí está el bytecode ofuscado
    ...

    n LOAD_GLOBAL? (__pyarmor__)
    n + 3 CALL_FUNCTION 0
    n + 6 POP_TOP
    n + 7 JUMP_ABSOLUTE 0
  • Guarde el objeto de código ofuscado como archivo .pyc o .pyo

Esos archivos ofuscados (.pyc o .pyo) pueden ser utilizados por el intérprete normal de Python, cuando esos objetos de código se llaman por primera vez

  • La primera operación es JUMP_ABSOLUTE, saltará para compensar n

  • En el desplazamiento n, la instrucción es llamar a PyCFunction. Esta función restaurará los códigos de bytes ofuscados entre el desplazamiento 3 yn, y colocará el código de bytes original en el desplazamiento 0. El siguiente código puede obtenerse mediante el siguiente código

        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)
    
  • Después de que esta función regrese, la última instrucción es saltar al desplazamiento 0. El código de bytes realmente se ejecuta ahora.

Hay una herramienta Pyarmor para ofuscar los scripts de Python de esta manera.

Jondy Zhao
fuente
1

usar cxfreeze (py2exe para linux) hará el trabajo.

http://cx-freeze.sourceforge.net/

está disponible en repositorios de ubuntu

Ali AlNoaimi
fuente
55
Creo que eso simplemente agrupa los archivos .pyc. Cython, Shed Skin y PyPy van más allá del bytecode.
Cees Timmerman
1

Hay una respuesta completa sobre cómo ocultar el código fuente de Python, que se puede encontrar aquí .

Las posibles técnicas discutidas son:
- usar bytecode compilado ( python -m compileall)
- creadores ejecutables (o instaladores como PyInstaller )
- software como servicio (la mejor solución para ocultar su código en mi opinión)
- ofuscadores de código fuente python

Miguel
fuente
El enlace va a example.com.
Darian
@Darian gracias por señalar eso. Actualicé el enlace.
Mike