Ocultar una contraseña en un script de python (solo ofuscación insegura)

Tengo un script en python que está creando una conexión ODBC. La conexión ODBC se genera con una cadena de conexión. En esta cadena de conexión tengo que incluir el nombre de usuario y la contraseña para esta conexión.

¿Hay una manera fácil de ocultar esta contraseña en el archivo (solo que nadie puede leer la contraseña cuando estoy editando el archivo)?

La encoding Base64 está en la biblioteca estándar y servirá para detener a los surfistas de hombro:

>>> import base64 >>> print base64.b64encode("password") cGFzc3dvcmQ= >>> print base64.b64decode("cGFzc3dvcmQ=") password 

Douglas F Shearer’s es la solución generalmente aprobada en Unix cuando necesita especificar una contraseña para un inicio de sesión remoto.
Agrega una opción –password-from-file para especificar la ruta y leer texto sin formato de un archivo.
El archivo puede estar en el área del usuario protegida por el sistema operativo. También permite a diferentes usuarios recoger automáticamente su propio archivo.

Para las contraseñas que el usuario de la secuencia de comandos no puede conocer, puede ejecutar la secuencia de comandos con permiso elavated y tener el archivo de contraseña de ese usuario raíz / administrador.

Aquí hay un método simple:

  1. Crea un módulo de python, llamémoslo peekaboo.py.
  2. En peekaboo.py, incluya tanto la contraseña como cualquier código que necesite esa contraseña
  3. Cree una versión comstackda, peekaboo.pyc, importando este módulo (a través de la línea de comandos de Python, etc.).
  4. Ahora, elimine peekaboo.py.
  5. Ahora puede importar alegremente peekaboo confiando solo en peekaboo.pyc. Dado que peekaboo.pyc se comstack en bytes, no es legible para el usuario ocasional.

Esto debería ser un poco más seguro que la deencoding de base64, aunque es vulnerable a un decomstackdor py_to_pyc.

Si está trabajando en un sistema Unix, aproveche el módulo netrc en la biblioteca estándar de Python. Lee las contraseñas de un archivo de texto separado (.netrc), que tiene el formato descrito aquí .

Aquí hay un pequeño ejemplo de uso:

 import netrc # Define which host in the .netrc file to use HOST = 'mailcluster.loopia.se' # Read from the .netrc file in your home directory secrets = netrc.netrc() username, account, password = secrets.authenticators( HOST ) print username, password 

La mejor solución, suponiendo que el usuario no pueda proporcionar el nombre de usuario y la contraseña en tiempo de ejecución, es probablemente un archivo de origen independiente que contiene solo la inicialización de la variable para el nombre de usuario y la contraseña que se importa a su código principal. Este archivo solo necesita ser editado cuando las credenciales cambian. De lo contrario, si solo te preocupan los surfistas de hombro con memoria promedio, la encoding de base 64 es probablemente la solución más fácil. ROT13 es demasiado fácil de decodificar manualmente, no distingue entre mayúsculas y minúsculas y conserva demasiado significado en su estado cifrado. Codifique su contraseña e identificación de usuario fuera del script de Python. Haga que el script decodifique en tiempo de ejecución para su uso.

Dar credenciales de scripts para tareas automatizadas es siempre una propuesta arriesgada. Su secuencia de comandos debe tener sus propias credenciales y la cuenta que utiliza no debe tener acceso más que exactamente lo que es necesario. Al menos la contraseña debe ser larga y bastante aleatoria.

¿Qué tal importar el nombre de usuario y la contraseña de un archivo externo al script? De esa manera, incluso si alguien hubiera obtenido el script, no obtendrían la contraseña automáticamente.

Base64 es el camino a seguir para sus necesidades simples. No hay necesidad de importar nada:

 >>> 'your string'.encode('base64') 'eW91ciBzdHJpbmc=\n' >>> _.decode('base64') 'your string' 

Este es un problema bastante común. Normalmente lo mejor que puedes hacer es

A) cree algún tipo de función de cifrado ceasar para codificar / decodificar (simplemente no rot13) o B) el método preferido es usar una clave de cifrado, al scope de su progtwig, codificar / decodificar la contraseña. En el que puede utilizar la protección de archivos para proteger el acceso a la clave. En esa línea, si su aplicación se ejecuta como un servicio / demonio (como un servidor web), puede poner su clave en un almacén de claves protegido por contraseña con la entrada de contraseña como parte del inicio del servicio. Le tomará a un administrador reiniciar su aplicación, pero tendrá una muy buena pretensión para sus contraseñas de configuración.

Su sistema operativo probablemente proporciona instalaciones para cifrar datos de forma segura. Por ejemplo, en Windows hay DPAPI (API de protección de datos). ¿Por qué no pedirle al usuario sus credenciales la primera vez que corres y luego guardarlos encriptados para las siguientes ejecuciones?

Más apreciación propia en lugar de convertir autenticación / contraseñas / nombre de usuario en detalles incrustados. FTPLIB es solo el ejemplo. ” pass.csv ” es el nombre del archivo csv

Guardar contraseña en CSV como a continuación:

nombre de usuario

contraseña de usuario

(Sin encabezado de columna)

Leyendo el CSV y guardándolo en una lista.

Usando los elementos de la Lista como detalles de autenticación.

Código completo.

 import os import ftplib import csv cred_detail = [] os.chdir("Folder where the csv file is stored") for row in csv.reader(open("pass.csv","rb")): cred_detail.append(row) ftp = ftplib.FTP('server_name',cred_detail[0][0],cred_detail[1][0]) 

Coloque la información de configuración en un archivo de configuración cifrado. Consulta esta información en tu código usando una clave. Coloque esta clave en un archivo separado por entorno y no la almacene con su código.

Si se ejecuta en Windows, podría considerar el uso de la biblioteca win32crypt. Permite el almacenamiento y recuperación de datos protegidos (claves, contraseñas) por parte del usuario que ejecuta el script, por lo que las contraseñas nunca se almacenan en texto claro o en formato ofuscado en su código. No estoy seguro de si existe una implementación equivalente para otras plataformas, por lo que con el uso estricto de win32crypt su código no es portátil.

Creo que el módulo se puede obtener aquí: http://timgolden.me.uk/pywin32-docs/win32crypt.html

para python3 la ofuscación usando base64 se hace de manera diferente:

 import base64 base64.b64encode(b'PasswordStringAsStreamOfBytes') 

lo que resulta en

 b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=' 

note la representación informal de la cadena, la cadena real está entre comillas

y la deencoding de nuevo a la cadena original

 base64.b64decode(b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=') b'PasswordStringAsStreamOfBytes' 

para usar este resultado donde se requieren objetos de cadena, el objeto de bytes se puede traducir

 repr = base64.b64decode(b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=') secret = repr.decode('utf-8') print(secret) 

Para obtener más información sobre cómo Python3 maneja los bytes (y las cadenas en consecuencia), consulte la documentación oficial .

Hay varias utilidades ROT13 escritas en Python en la ‘Red – solo google para ellas. ROT13 codifica la cadena fuera de línea, cópiela en la fuente, decodifique en el punto de transmisión.

Pero esta es una protección muy débil …

¿Conoces el foso?

https://pypi.python.org/pypi/pit (solo en py2 (versión 0.3))

https://github.com/yoshiori/pit (funcionará en py3 (versión actual 0.4))

test.py

 from pit import Pit config = Pit.get('section-name', {'require': { 'username': 'DEFAULT STRING', 'password': 'DEFAULT STRING', }}) print(config) 

Correr:

 $ python test.py {'password': 'my-password', 'username': 'my-name'} 

~ / .pit / default.yml:

 section-name: password: my-password username: my-name 

Esto no responde precisamente a tu pregunta, pero está relacionado. Iba a agregar como comentario pero no estaba permitido. He estado lidiando con este mismo problema, y ​​hemos decidido exponer el script a los usuarios que usan Jenkins. Esto nos permite almacenar las credenciales de db en un archivo separado que está cifrado y protegido en un servidor y no es accesible para los no administradores. También nos permite un poco de acceso directo para crear una IU y acelerar la ejecución.