¿Dónde almacenar la clave privada?

22

Digamos que quiero que algunas partes de mi software estén encriptadas. Por ejemplo, las credenciales para una base de datos, etc. Necesito almacenar esos valores en algún lugar, pero hacerlo en texto sin cifrar facilitaría que un atacante obtenga acceso no autorizado.

Sin embargo, si cifro algún texto en claro, ¿dónde guardo la clave? Cualquier cosa a la que tenga acceso el software, un atacante determinado tendría acceso, sin importar el nivel de ofuscación:

  • Digamos que la clave está protegida por el modelo de seguridad del sistema de archivos; pero ¿qué pasa con los superusuarios (maliciosos) o las plataformas que no brindan tanta fidelidad?
  • O la clave está codificada en binarios de software, pero siempre se puede descompilar y ¿qué pasa con el software de código abierto o el código interpretado?
  • Si se genera la clave, dicho algoritmo debería ser determinista (presumiblemente) y luego se aplica el mismo problema a la semilla.
  • etc.

¡La criptografía es tan fuerte como el eslabón más débil de su cadena y parece una muy floja! Suponiendo que es la herramienta adecuada para el trabajo (por favor), ¿cómo se puede proteger esa información con solidez?


Con respecto a la herramienta adecuada para el trabajo: probablemente, por ejemplo, en el caso del acceso al servicio (DB, servidores de autenticación, etc.), restringiría el acceso en este nivel con una cuenta de servicio, tal vez con algún nivel de servicio auditoría, etc. y tener las credenciales en texto sin formato no es una preocupación.

Para mí, sin embargo, eso todavía parece inadecuado: ¡no quiero que nadie mire donde no debería estar!

Xophmeister
fuente
66
Puede encontrar varias publicaciones en Security.SE para ser de su interés. Notaré que algunos marcos e idiomas proporcionan soporte especializado para esto (por ejemplo, secciones de configuración encriptadas en .net).
Brian
99
desafortunadamente, no hay mucho que puedas hacer contra un "superusuario malicioso". Dado que su software necesita acceso a las claves, también lo hará cualquier superusuario, ya que tienen la capacidad de alterar / omitir casi cualquier ACL que pueda implementar.
DXM
16
La única forma absolutamente segura de evitar tener que confiar un secreto al usuario es evitar la necesidad de dicho secreto. Una solución común es ejecutar el software en un servidor bajo su control, y solo distribuir un front-end desprotegido a través del cual el usuario puede autenticarse en el servidor y luego consumir servicios del servidor.
amon
2
La respuesta de Amon no se limita a un usuario, sino a cualquier cliente. DXM también plantea el punto de que no puede proteger su sistema de alguien que quiera manipularlo y no debe gastar la energía para dificultar que lo hagan. En cambio, gaste la energía en el producto para que no tengan interés en hacerlo
Kevin
3
Lo mejor que puede hacer con los clientes maliciosos es restringirlos a una API de servicio bien definida, sin darles acceso directo a la base de datos. Realmente no puedes hacer nada más que eso, ya que no puedes ocultar un secreto en el cliente.
CodesInChaos

Respuestas:

25

En primer lugar, no me referiría a mí mismo como un experto en seguridad, pero he estado en la posición de tener que responder esta pregunta. Lo que descubrí me sorprendió un poco: no existe un sistema completamente seguro . Bueno, supongo que un sistema completamente seguro sería uno en el que todos los servidores estén apagados :)

Alguien que trabajaba conmigo en ese momento describió el diseño de un sistema seguro en términos de elevar el listón a los intrusos. Entonces, cada capa de seguridad disminuye la oportunidad de un ataque.

Por ejemplo, incluso si pudiera asegurar perfectamente la clave privada, el sistema no es completamente seguro. Pero, usar correctamente los algoritmos de seguridad y estar actualizado con parches eleva el listón. Pero sí, una súper computadora lo suficientemente potente y con suficiente tiempo puede romper el cifrado. Estoy seguro de que todo esto se entiende, así que volveré a la pregunta.

La pregunta es clara, así que primero trataré de abordar cada uno de sus puntos:

Digamos que la clave está protegida por el modelo de seguridad del sistema de archivos; pero ¿qué pasa con los superusuarios (maliciosos) o las plataformas que no brindan tanta fidelidad?

Sí, si usa algo como Windows Key Store o una clave privada TLS cifrada con contraseña, está expuesto a los usuarios que tienen la contraseña (o acceso) a las claves privadas. Pero, creo que estará de acuerdo en que eleva el listón. Las ACL del sistema de archivos (si se implementan correctamente) proporcionan un nivel de protección bastante bueno. Y usted está en condiciones de examinar y conocer personalmente a sus súper usuarios.

O la clave está codificada en binarios de software, pero siempre se puede descompilar y ¿qué pasa con el software de código abierto o el código interpretado?

Sí, he visto claves codificadas en binarios. Nuevamente, esto eleva un poco el listón. Alguien que ataque este sistema (si es Java) tiene que entender que Java produce código de bytes (etc.) y debe entender cómo descompilarlo y leerlo. Si está utilizando un lenguaje que escribe directamente en el código de la máquina, puede ver que esto eleva el listón un poco más alto. No es una solución de seguridad ideal, pero podría proporcionar cierto nivel de protección.

Si se genera la clave, dicho algoritmo debería ser determinista (presumiblemente) y luego se aplica el mismo problema a la semilla.

Sí, esencialmente el algoritmo se convierte en la información de clave privada para crear la clave privada. Entonces, ahora necesitaría estar protegido.

Por lo tanto, creo que ha identificado un problema central con cualquier política de seguridad, gestión de claves . Tener una política de gestión clave es fundamental para proporcionar un sistema seguro. Y, es un tema bastante amplio .

Entonces, la pregunta es, ¿qué tan seguro debe ser su sistema (y, por lo tanto, la clave privada)? ¿Qué altura, en su sistema, necesita elevar la barra?

Ahora, si está dispuesto a pagar, hay algunas personas que producen soluciones para esto. Terminamos usando un HSM (Módulo de seguridad de hardware) . Básicamente es un servidor a prueba de manipulaciones que contiene una clave en el hardware. Esta clave se puede utilizar para crear otras claves utilizadas para el cifrado. La idea aquí es que (si se configura correctamente), la clave nunca abandona el HSM. Los HSM cuestan mucho . Pero en algunas empresas (digamos que proteger los datos de la tarjeta de crédito), el costo de una violación es mucho mayor. Entonces, hay un equilibrio.

Muchos HSM utilizan tarjetas clave de mantenimiento y administrador de las funciones. Un quórum de tarjetas de clave (digamos 5 de 9) debe colocarse físicamente en el servidor para cambiar una clave. Por lo tanto, esto eleva el listón bastante alto al permitir solo una brecha si un quórum de superusuarios conspira.

Puede haber soluciones de software que brinden características similares a un HSM, pero no estoy al tanto de cuáles son.

Sé que esto solo sirve para responder la pregunta, pero espero que esto ayude.

Davin Tryon
fuente
2
"Bueno, supongo que un sistema completamente seguro sería uno en el que todos los servidores están apagados" y no existe forma de encenderlos.
StingyJack
2

Lo que quieres no se puede hacer.

Digamos que la clave está protegida por el modelo de seguridad del sistema de archivos; pero ¿qué pasa con los superusuarios (maliciosos) o las plataformas que no brindan tanta fidelidad?

Básicamente quieres protección contra personas que se vuelven maliciosas En su modelo, en algún momento alguien tendrá acceso a la clave. ¿Qué pasa si esa persona es maliciosa? ¿Qué pasa si USTED es malicioso? Mire, el problema, como usted dice, es irresoluble, excepto por no tener una clave.

Por lo tanto, no trabaje con credenciales de base de datos sino con otros mecanismos de autenticación. Pero no importa qué, alguien en algún momento necesita acceso a los datos y esa persona puede ser maliciosa.

Pieter B
fuente
2

Este es uno de esos problemas que realmente no se pueden resolver al mismo nivel en que se creó. Tendremos que dar un paso atrás hacia algunas filosofías fundamentales y seguir la cascada con la esperanza de una resolución.

La primera filosofía es "nunca confiar en el cliente", y la estrechamente relacionada "si realmente quieres guardar un secreto, ¡no se lo digas a nadie!"

Un ejemplo simple son las credenciales de la base de datos, como usted mencionó. Obviamente, desea que su cliente tenga acceso a él, pero no un extraño desconocido de Internet, por lo que necesita algún tipo de sistema de identidad / verificación / inicio de sesión. Pero la premisa central de ocultar esto es un problema: si el usuario mismo debe poseer un secreto, pero no quiere que sepan cuál es ese secreto, todo lo que puede hacer es ocultarlo o dificultar que se abra " el paquete secreto ". Pero aún pueden averiguarlo, ¡así que será mejor que tengas un plan de respaldo!

La solución más fácil es "no hagas eso". Use las credenciales de la cuenta del usuario para permitir el acceso a nivel de cliente a la base de datos para el software, y eso es todo. Si el cliente se vuelve malicioso, el peor de los casos debería ser que el cliente pueda arruinar sus propios datos. Eso es. Su base de datos y sistema deberían, como máximo, ahora contener entradas no deseadas de ese cliente, únicamente para ese cliente, sin que nadie más (incluido usted) sufra el caos.

Hay casos de uso específicos en los que solo desea que el software implementado haga algo, pero no todos en el mundo puedan conectarse y hacer lo mismo, pero para eso solo está ocultando secretos y la única buena razón para hacerlo es simplemente reducir dolores de cabeza o actividad del sistema. Si su información oculta se convierte en conocimiento común, es mejor que no rompa el juego, solo que en el peor de los casos sea molesto.

Si se encuentra en uno de esos casos de uso limitado, se trata solo de ofuscación, que se trata de ser creativo. Realmente se parece mucho a Code Golf, excepto que tú eres el que crea el rompecabezas. Eso es todo lo que realmente es: un rompecabezas. Y a la gente le gusta resolver acertijos, así que de nuevo, será mejor que alguien lo resuelva.

Pero para la mayoría de las cosas en el mundo, es mejor operar sin preocuparse de tener que guardar un secreto para el usuario. En cambio, la mejor práctica es simplemente dejar que el usuario entre en el secreto, hacer que sea su responsabilidad ayudar a protegerlo (su nombre de usuario y contraseña, por ejemplo) y limitar el riesgo a la baja de lo que sucede si el secreto se revela o se abusa.

En los verdaderos contextos criptográficos / de seguridad de "gestión de claves", la respuesta de "dónde almacenar la clave privada" es "¡en otro lugar!" El cifrado es protección punto a punto, y el cifrado de clave pública-privada está diseñado para proteger la información en tránsito a través del tiempo y el espacio. La clave privada es inherentemente vulnerable, y protegerla no es realmente una cuestión de cifrado superpuesto, sino que la protege completamente contra el acceso. Y si el sistema debe acceder a él, entonces el sistema en sí debe estar protegido, y no puede hacerlo en la máquina de un cliente. Siempre pueden ejecutar una VM, volcar la RAM, oler su tráfico de red, instalar un proxy o NIC virtual, descompilar los ejecutables ... no se involucren voluntariamente en esa batalla perdida.

Ahora, si necesita hacer algo como DRM, donde su necesidad de almacenar un secreto se basa realmente en controlar el uso del software en sí, esa es otra situación completamente diferente .


TLDR: no guardes secretos del usuario, guarda secretos con el usuario.

BrianH
fuente
1

Uno de los sistemas que uso actualmente funciona de esta manera.

  • Comienzo con un formulario de inicio de sesión del servicio de autenticación. Utiliza la autenticación de dos factores para asegurarse de que soy quien digo ser.
  • Recibo un certificado SSL temporal que puedo usar para acceder al servicio protegido. El servicio realiza un seguimiento de los certificados que acepta.
  • Mis intercambios están encriptados por este certificado de espionaje. Intentar descifrarlo no es muy útil ya que caducará.
  • El certificado caduca rápidamente (en varias horas), pero no demasiado rápido, de modo que no necesito proporcionar una contraseña para cada interacción.
  • El certificado puede ser revocado instantáneamente en el otro lado.

Por supuesto, el servicio protegido se ejecuta en algún lugar fuera de mi alcance. Podría ejecutarse en mi máquina con una cuenta diferente (y posiblemente en un contenedor), pero tengo privilegios de superusuario y podría intentar sortear las restricciones.

Básicamente, si tiene un superusuario malintencionado, todas las apuestas están desactivadas. Y deberías asumir la presencia de un superusuario malicioso en su modelo de amenaza.

Por lo tanto, debe aislar su servicio protegido de la máquina accesible para el cliente. Mueva el servicio protegido a una máquina solo accesible a través de la red. Coloque a sus clientes en máquinas virtuales que les impidan llegar al resto de la máquina física donde se ejecuta su servicio protegido.

Si su servicio protegido no es tan valioso como para poder controlar tales medidas, vaya con cualquier almacén de claves cifradas que le proporcione el sistema operativo: tanto Windows, Linux como OSX tienen implementaciones de llavero.

9000
fuente
-1

En mi opinión, la única forma de mantener esto completamente seguro es cifrar la clave / contraseña con una frase de contraseña para desbloquear. De esta manera, se debe dar la frase de contraseña para cada inicio o uso del secreto. No es demasiado útil.

Otra forma podría ser que el sistema de seguridad sea la cuenta de la base de datos. No muy escalable ...

Si cada usuario en un sistema tiene su propia cuenta de base de datos, y esas cuentas se crearon previamente para que la aplicación no tenga derechos para crear cuentas en la base de datos en nombre de un usuario, sin embargo, podría acercarse bastante. Tampoco es una buena solución, así que supongo que debe tener un acceso de lectura muy restringido en los archivos de configuración y confiar en sus superusuarios.

polve
fuente