Proteger claves privadas en servidores desatendidos

2

Supongamos que tengo un servidor (por ejemplo, una frambuesa pi conectada a Internet) que necesita acceder de forma autónoma a algún servicio de terceros (por ejemplo, banda, aws, etc.). Para utilizar este servicio de terceros a través de su SDK, debo proporcionarle una clave secreta para inicializar el SDK. Mi pregunta es, ¿cómo almaceno esta clave secreta en el servidor de forma segura?

No quiero almacenar la clave en texto plano, pero cifrarla parece que no ayudaría. Si está cifrado, tengo que proporcionar algún tipo de credenciales que el servidor pueda usar para desencriptar las claves. Entonces estas credenciales están en el servidor, y obtener acceso a ellas le permite desencriptar la clave de todos modos para que nada cambie.

Siento que cifrar las claves y luego proporcionar la contraseña de descifrado es como colocar objetos de valor dentro de cajas de zapatos anidadas y decir "¡HA! ¡Nunca podrán acceder a la caja de zapatos interior porque tienen que abrir la externa primero!"

¿Cuál es la mejor práctica aquí?

    
pregunta Logister 15.01.2018 - 02:58
fuente

2 respuestas

1

Comencemos con las restricciones:

  1. Necesita algún tipo de secreto compartido para enviarlo a un servicio para autenticarse, por lo que necesita poder acceder al texto sin formato.
  2. Esto debe hacerse de manera automatizada (desatendida).
  3. Le gustaría proteger las credenciales tanto como sea posible.

Primero, debemos reconocer que es imposible protegerlos por completo , y que puede o no valer la pena hacerlo. Si alguien puede ejecutar el código en su servidor, puede hacer casi cualquier cosa que pueda hacer el servicio legítimo, incluida la lectura de las claves y el uso de las mismas para realizar solicitudes a servicios remotos. Sin embargo, dependiendo de la cantidad de inconvenientes que estés dispuesto a sufrir, puedes hacer que sean más difíciles de usar.

Primero, comencemos con las "mejores prácticas" que tienen poco o ningún impacto en la capacidad de usarlas.

  1. Ejecute cada servicio en su servidor como un usuario separado. Lo ideal es agregar un sistema MAC como SELinux o AppArmor para contener un compromiso.
  2. Almacene claves / secretos en archivos que solo se pueden leer con el servicio adecuado y bloquee los permisos lo más posible. (0400 en Linux.)
  3. Asegúrese de que las claves brinden el menor acceso necesario en el extremo remoto. ¿Cargando archivos a un cubo S3? Cree un token de acceso con solo ese permiso. (De esta manera, si está comprometido, limita el daño que puede hacer un atacante).

Si necesita ir más allá de este punto, puede hacer algunas cosas:

  1. Almacena los secretos en un módulo de hardware. (En particular, si el criptográfico asimétrico es una opción). Esto no impedirá que un atacante use sus credenciales, pero evitará que se filtren.
  2. Use un módulo de hardware que requiera interacción humana. Cuando se inicia el servicio, deberá ingresar un PIN, y luego el servicio mantendrá la clave desencriptada solo en la memoria. (Por supuesto, un buen atacante probablemente puede sacar la clave de la memoria, pero eleva el nivel).

Más allá de este punto, nos metemos en el "estúpido para la mayoría de las aplicaciones": espaciamiento de aire, tokens interactivos que requieren PIN para cada firma, etc. La naturaleza desatendida desaparecerá rápidamente.

    
respondido por el David 15.01.2018 - 03:49
fuente
0

Si el servidor está comprometido, no hay manera de hacerlo de manera segura porque el atacante puede hacer lo que quiera, por ejemplo, interceptar la contraseña. Observe el enfoque de las claves públicas en gnupg: almacenan el secreto cifrado en el disco y lo descifran utilizando una clave proporcionada por el usuario en la memoria. Este enfoque funciona si puede tener la interacción del usuario. Por lo que sé, si no hay interacción humana, es difícil asegurar esta clave.

    
respondido por el Anton Althoff 15.01.2018 - 03:17
fuente

Lea otras preguntas en las etiquetas