¿Cómo almacenar contraseñas en un sitio web remoto?

2

Diga que quiero crear una API pública para acceder a un sitio web que no tenga una. El sitio web está protegido por un esquema de nombre de usuario / contraseña estándar y la implementación de la API utilizará el raspado para obtener los datos de él.

¿Cuál sería la mejor manera de manejar las contraseñas en este escenario?

Mi mejor idea actual es esta. Obtenga el nombre de usuario y la contraseña en un formulario HTML en mi sitio (el mismo que sirve a la API), y generó una URL para acceder a la API que incluye una gota cifrada de nombre de usuario y contraseña. El cifrado es simétrico AES256 basado en una clave almacenada solo en el servidor API. Cuando el usuario accede a la URL de la API, el servidor de la API descifra las credenciales y accede al sitio web remoto.

Como un nivel adicional de protección, estoy pensando en ejecutar la API como CGI, de modo que solo un proceso de corta duración esté expuesto a las credenciales de texto sin formato.

¿Eso tiene algún sentido? ¿Hay alguna solución estándar para este tipo de problema?

[Editar]

Posible duplicado: ¿Cómo almacenar la frase de contraseña en esta situación?

    
pregunta gooli 29.12.2014 - 19:27
fuente

1 respuesta

3

Su solución actual funcionaría, sin embargo, puede mantener la información en su servidor mediante el seguimiento de una sesión. Cuando un usuario envía sus credenciales de inicio de sesión, puede almacenarlas en una base de datos (posiblemente encriptada) y luego emitirles un ID de sesión único (debería ser difícil predecir el ID de sesión, por ejemplo, crypto rand + hash).

Una vez que el usuario haya obtenido la clave de sesión, enviará esa identificación junto con cada solicitud a su servidor. Cuando verifica que esta clave de sesión es válida, obtiene el nombre de usuario / contraseña de la base de datos y realiza la solicitud en nombre del usuario. Después de cierto tiempo, invalidará esta clave de sesión y la eliminará junto con la información de inicio de sesión de su base de datos. Esto ayudaría a protegerse contra los ataques de estilo de reproducción.

Si incluye la información de inicio de sesión real y no tiene algún tipo de antigüedad, un atacante podría obtener la URL utilizada para acceder al sistema y, posiblemente, realizar solicitudes en nombre del usuario. Por supuesto, esto depende de cómo configure la URL, etc.

Sin embargo, por lo general, este tipo de situación se maneja almacenando las credenciales localmente en algún tipo de almacenamiento seguro (por ejemplo, cifrado) y emitiendo algún tipo de identificador de sesión temporal.

Si bien puede haber algún beneficio en el uso de procesos de ejecución corta, es probable que tenga más costo que beneficio. Si un atacante está en el punto en el que puede leer la memoria en sus procesos, el hecho de que el tiempo en la memoria sea breve no ayudará mucho. Además, es probable que aún esté almacenando las credenciales cifradas en algún lugar de su servidor (por ejemplo, los registros de acceso http), junto con la clave de cifrado (que supongo que se encuentra en una base de datos). Si el atacante tiene acceso a ambos, las credenciales se verán comprometidas. Dependiendo del idioma que esté utilizando para escribir la aplicación, puede haber alguna manera de poner a cero la memoria una vez que haya terminado con la información confidencial.

Si usa marcas de tiempo en la URL, deberá asegurarse de que no se pueda alterar la marca de tiempo (HMAC, AES-GCM, etc.). Mantener los datos de credenciales, encriptados o no, también representa un problema que controla la información. Si sospecha que su clave de cifrado ha sido comprometida, puede eliminar fácilmente los credenciales de su servidor. Si las credenciales están en direcciones URL potencialmente dispersas por Internet en cachés de navegadores, etc., no podrá mitigar las fugas.

Si almacena las credenciales en la base de datos, junto con el material que use para obtener la clave, tendrá mucho más control sobre los datos. Suponiendo que tiene su aplicación de base de datos protegida, es sin duda más seguro. Yo sugeriría usar diferentes claves para cada conjunto de credenciales, y usar algún tipo de KDF ( enlace ) para derivar la clave, En lugar de almacenar la clave en texto plano en la base de datos. También puede incluir una parte del material de derivación de claves en el ID de sesión que emita al usuario.

Por supuesto, si alguien tiene acceso completo a su servidor, incluida la base de datos y / o el espacio de VA de sus procesos CGI, las credenciales se comprimirán, pero eso es cierto con casi cualquier solución.

Si estuviera escribiendo esta aplicación, usaría los identificadores de sesión para vincular las solicitudes de un usuario a un conjunto de credenciales. Usaría una tabla de base de datos que contiene campos para el ID, la hora de creación, la última vez que se vio, el nombre de usuario, la contraseña y la semilla de derivación de clave (esta parte depende de cómo derivar las claves). El ID de sesión que emitiría al usuario sería un valor grande y difícil de adivinar (almacenado en el campo de ID), combinado con una parte del material necesario para generar la clave (este material no se almacenaría en el servidor, por lo tanto, se necesitan tanto una identificación de sesión válida como el material almacenado en el servidor para descifrar las credenciales).

Por ejemplo, un ID de sesión puede tener este aspecto:

d7be62755db80ccefb7d802fde153145b6e9_bdb8f9bf599293fd65a020dba1ecd

La primera parte sería la parte de identificación y la segunda mitad de los datos necesarios para obtener la clave.

Cuando se realiza una solicitud, la parte de identificación de la identificación de sesión se verificará, y la clave de descifrado se generará utilizando la parte de material de clave suministrada por el usuario (a través de la identificación de sesión) y la parte almacenada en la base de datos. Una vez que se genere la clave, descifrarás y usarás los credenciales.

De esta manera, si un atacante obtiene acceso a la base de datos, no tiene todo lo que necesita para descifrar todas las credenciales. Necesitarían un ID de sesión para cada conjunto de credenciales que desean descifrar.

Para retrasar las sesiones, puedes tener un trabajo cron, o algún otro mecanismo, para eliminar sesiones caducadas de la base de datos.

    
respondido por el superultranova 29.12.2014 - 20:45
fuente

Lea otras preguntas en las etiquetas