password protection - proteger - Almacenamiento de contraseñas en control de fuente
programa para guardar contraseñas sin que se den cuenta (6)
Almacenamos todas nuestras contraseñas de aplicaciones y bases de datos en texto sin formato en control de fuente. Hacemos esto ya que nuestro proceso de compilación / implementación genera los archivos de configuración necesarios y también los despliegues reales que requieren estas contraseñas (es decir: la ejecución de SQL contra una base de datos requiere que inicie sesión en el DB utilizando credenciales válidas). ¿Alguien ha tenido una necesidad similar en la que pudo implementar este tipo de funcionalidad sin almacenar las contraseñas en texto plano?
Almacenar contraseñas en forma cifrada. Escriba una rutina personalizada que descifre las contraseñas y actualice los archivos de configuración en tiempo de compilación. Esto se puede integrar fácilmente con la herramienta de compilación como Ant.
Creé sistemas en los que los pares de ID de usuario / contraseña no forman parte del código. La clave es configurar un mecanismo de configuración específico del sitio. Luego puede poner esa información en la casilla en cuestión, sin que sea parte de la base de código.
Hay una ventaja: no solo puede tener contraseñas diferentes para distintas reducciones de código, sino también para diferentes desarrolladores. :-)
No mencionó el idioma, así que aquí está una solución de vb.net que usamos:
Imports System.Web.Security
Imports System.Security.Cryptography
Imports System.Text
Imports Microsoft.Win32
Public Class myCrypt
Private myKey As String = "somekeyhere"
Private cryptDES3 As New TripleDESCryptoServiceProvider()
Private cryptMD5Hash As New MD5CryptoServiceProvider()
Private Function Decrypt(ByVal myString As String) As String
cryptDES3.Key = cryptMD5Hash.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey))
cryptDES3.Mode = CipherMode.ECB
Dim desdencrypt As ICryptoTransform = cryptDES3.CreateDecryptor()
Dim buff() As Byte = Convert.FromBase64String(myString)
Decrypt = ASCIIEncoding.ASCII.GetString(desdencrypt.TransformFinalBlock(buff, 0, buff.Length))
End Function
Private Function Encrypt(ByVal myString As String) As String
cryptDES3.Key = cryptMD5Hash.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey))
cryptDES3.Mode = CipherMode.ECB
Dim desdencrypt As ICryptoTransform = cryptDES3.CreateEncryptor()
Dim MyASCIIEncoding = New ASCIIEncoding()
Dim buff() As Byte = ASCIIEncoding.ASCII.GetBytes(myString)
Encrypt = Convert.ToBase64String(desdencrypt.TransformFinalBlock(buff, 0, buff.Length))
End Function
End Class
Si lo hace en C, puede almacenarlo como una matriz de caracteres y poner los caracteres como referencias decimales. No estoy seguro si esto romperá las cuerdas o no, pero podría ayudar a aliviar parte de ese problema.
char pass[]={72, 101, 108, 108, 111};
Si su plan es almacenar todo el código y la información de configuración para ejecutar un sistema de producción directamente desde el control de la versión, y sin la intervención del personal, está equivocado. ¿Por qué? Esto es solo una violación del antiguo axioma de seguridad "nunca escriba su contraseña". Hagamos una prueba por negación.
Primer corte, tiene contraseñas de texto sin formato en los archivos de configuración. Eso no es bueno, pueden ser leídos por cualquiera que pueda ver los archivos.
Segundo corte, encriptaremos las contraseñas! Pero ahora el código necesita saber cómo descifrar las contraseñas, por lo que debe colocar la clave de descifrado en algún lugar del código. El problema acaba de bajar un nivel.
¿Qué tal el uso de claves públicas / privadas? Mismo problema que las contraseñas, la clave debe estar en el código.
El uso de un archivo de configuración local que no está almacenado en el control de la versión todavía coloca la contraseña y los medios para leerlos si están encriptados, en el disco y disponibles para un atacante. Puedes endurecer un poco las cosas asegurándote de que los permisos del archivo de configuración sean muy limitados, pero si la caja se enruta, estás jodido.
Lo que nos lleva a explicar por qué poner contraseñas en el disco es una mala idea. Viola el concepto de un firewall de seguridad. Una máquina comprometida que contiene información de inicio de sesión significa que otras máquinas estarán en peligro. Una máquina mal mantenida puede derribar toda su organización.
En algún momento, un humano tendrá que inyectar el secreto crítico para comenzar la cadena de confianza. Lo que podría hacer es encriptar todos los secretos en el código y luego, cuando el sistema se inicie, un humano ingrese manualmente la clave para descifrar todas las contraseñas. Es como el sistema de contraseña maestra que usa Firefox. Está abierto al abuso ya que una vez que una contraseña se ve comprometida, muchos sistemas pueden verse comprometidos, pero es conveniente y probablemente más seguro ya que los usuarios solo tienen que recordar una contraseña y es menos probable que la escriban.
El toque final es garantizar que la información de inicio de sesión se vea comprometida (y siempre debe asumir que lo será) que A) el atacante no puede hacer mucho con ella y B) que puede cerrar rápidamente las cuentas comprometidas. El primero significa dar a las cuentas solo el acceso que necesiten. Por ejemplo, si su programa solo necesita leer desde una base de datos, inicie sesión en una cuenta restringida a SELECCIONAR. En general, elimine todos los accesos y luego agréguelos solo cuando sea necesario. Sé tacaño sobre los derechos a eliminar para que no te visite el pequeño Bobby Tables .
Esto último significa que le da a cada usuario / organización / proyecto su propio inicio de sesión, incluso si pueden tener los mismos derechos y privilegios y acceder a los mismos datos. Es un poco más complicado, pero significa que si un sistema se ve comprometido, puede cerrar rápidamente esa cuenta sin cerrar todo su negocio.
Supongo que el objetivo es que no desee que las contraseñas privadas de su empresa estén disponibles, encriptadas, descifradas, o de otra manera, a cualquier persona que de otro modo debería tener acceso al resto de la fuente.
Así es como lo hago. Dupliqué este patrón de TikiWiki, que también lo hace.
en algún archivo que normalmente contiene contraseñas, configúrelos en valores ficticios, no importa qué. Establézcalo como lo que su cliente debería ver. Ponga un comentario cerca para que los desarrolladores dejen este archivo solo y modifiquen un segundo archivo.
En el segundo archivo, que se crea si no está allí, ingrese las contraseñas reales. haga arreglos para que este archivo sea incluido, importado, lo que sea, por el primer archivo.
Haga arreglos para que su control de origen ignore ese archivo. Podría verse algo como esto:
# in .gitignore
localsettings.py
# in settings.py
## Alter this value to log into the snack machine:
## developers: DON''T alter this, instead alter ''localsettings.py''
SECRET_VALUE = ""
try:
from localsettings import *
except:
pass
# in localsettings.py
SECRET_VALUE = "vi>emacs"