La mejor manera razonable de almacenar un secreto de manera segura

7

Estoy trabajando en un software que necesita almacenar y usar secretos.

Estos secretos pueden ser, por ejemplo:

  • una contraseña para conectarse a una base de datos
  • un secreto de cliente para una OAuth 2.0 client_credentials grant.

Necesito almacenar estas contraseñas en algún lugar (preferiblemente en algún tipo de archivo de configuración) y protegerlas con seguridad razonable .

Seguridad razonable significa: no hay una solución pesada basada en hardware como HSM o una infraestructura complicada (PKI, ...).

El software está en Java, debería ejecutarse en cualquier lugar donde Java pueda ejecutarse (especialmente Windows, GNU / Linux, Solaris, AIX).

No puede confiar en un sistema operativo o una herramienta específica de distribución como el almacén de claves de GNOME, KDE Wallet o cualquiera de estos, a menos que Java proporcione una forma de manejarlos (pero lo dudo).

Pensé en usar la criptografía simétrica para cifrar los secretos al configurar el software y descifrarlos en tiempo de ejecución cuando sea necesario. Pero no sé cómo manejar la clave de cifrado.

He encontrado 4 posibles soluciones:

  1. Use PBKDF2 (SHA256-AES256-CBC) o simple AES256-CBC con una clave criptográfica codificada y, opcionalmente, alguna ofuscación de código (con ProGuard )
    • Hay un CWE dedicado a eso: CWE-321 - Uso de clave criptográfica codificada . Así que dudo que esta sea la solución.
  2. Use PBKDF2 (SHA256-AES256-CBC) o simple AES256-CBC con una clave en un archivo en el sistema de archivos
    • Expone la clave en un archivo que debe estar protegido de alguna manera.
      • sistema de archivos encriptado y / o
      • ACL forzada
      • ¿Algo más?
  3. Usa el almacén de claves de Java
    • El almacén de claves de Java necesita una contraseña para desbloquear, entonces, ¿dónde almacenar la contraseña del almacén de claves de Java? ¿Cómo protegerlo? La serpiente está comiendo su propia cola ...
    • De alguna manera equivalente a 2
  4. usar criptografía de caja blanca
    • Ha mostrado algunas debilidades y es más o menos equivalente a la ofuscación. (que está dentro de la opción 1).
    • No estoy seguro de que la implementación de Java de WBC sea madura.

He visto esa pregunta: Prácticas para almacenar el nombre de usuario / contraseña en aplicaciones web .

Entonces, mi pregunta aquí es: ¿Cuál es la "mejor" opción razonable para proteger mis datos secretos?

Creo que 2 es mejor, después de todo es simple, y la protección de la clave secreta dependería del sistema operativo en lugar del software en sí, al igual que OpenSSH pero no estoy totalmente convencido.

EDIT:

PBKDF2 podría reemplazarse por cualquier otro algoritmo de derivación de clave de base de contraseña, como el algoritmo de derivación de clave PKCS # 12 v1.

Bonus:

Si tuviera que elegir entre PBKDF2 (SHA256-AES256-CBC) o simple AES256-CBC , ¿cuál sería la mejor?

  • Se dice que PBKDF2 es bueno para proteger las contraseñas porque es 'lento'. Y fue diseñado para eso.
  • AES256-CBC es más simple (no es necesario salt / hash / iterar la clave como en PBKDF2)
pregunta superbob 21.01.2016 - 15:17
fuente

2 respuestas

2

Supongo que su modelo de amenaza es un atacante que obtiene acceso para leer archivos en su servidor web a través de algún tipo de vulnerabilidad web. De lo contrario, debería cuestionar qué está mitigando exactamente con su estrategia de cifrado propuesta.

Si lo es, una opción similar a 2 es probablemente la más sencilla.

Yo usaría AES128-CBC como el algoritmo para una clave de cifrado de clave. Con una clave de cifrado de 128 bits generada por CSPRNG, no es necesario utilizar un algoritmo de estiramiento de claves. Los algoritmos como PBKDF2 solo son necesarios cuando intenta proteger contraseñas débiles proporcionadas por el usuario. Si puede configurar las teclas usted mismo, simplemente asegúrese de que tengan la fuerza de bits necesaria.

AES256 es más lento y sin seguridad adicional sobre AES128.

Asegúrese de que su archivo de configuración y su archivo de clave estén bloqueados por las listas de control de acceso.

Archivo de claves:

<128 bit random key>

Solo se puede leer con una cuenta de servicio personalizada.

Archivo de configuración:

Passwords to systems, encrypted by the key in the Key file.

Solo se puede leer por la identidad del servidor web.

Asegúrese de que su servidor web no pueda servir estos archivos (por ejemplo, example.com/config.txt no funcionará). La forma en que debería funcionar es que tiene una cuenta de servicio que ejecuta un proceso. El servicio web llama a este proceso y le pide al servicio que descifre la contraseña del archivo de configuración. El servicio valida que solo el proceso del servidor web puede llamarlo.

Esto protegerá tus secretos de cualquier explotación de LFI en tu sistema o servidor porque un atacante en el contexto del usuario del servidor web no tendrá permiso para leer el archivo de clave o descifrar cualquier credencial en tu archivo de configuración.

No protegerá contra el acceso físico, el acceso lógico al sistema por parte de otra cuenta de nivel de administrador o cualquier vulnerabilidad que permita llamar a un proceso. Básicamente, solo protegería contra las lecturas de archivos del archivo de configuración directamente por la identidad de la web (el usuario en el que se ejecuta el sitio web). Si esto no es una preocupación, entonces no hay necesidad de cifrar los secretos en absoluto, lo único que realmente protegería sería la observación casual de las partes que pueden ver el archivo de configuración.

    
respondido por el SilverlightFox 22.01.2016 - 12:06
fuente
0

Si está usando Java, ¿no debería estar usando el KeyStore de Java?

enlace

  

Esta clase representa una instalación de almacenamiento para claves y certificados criptográficos.

     

Un KeyStore gestiona diferentes tipos de entradas. Cada tipo de entrada implementa la interfaz KeyStore.Entry. Se proporcionan tres implementaciones básicas de KeyStore.Entry:

     

KeyStore.PrivateKeyEntry   Este tipo de entrada contiene una PrivateKey criptográfica, que se almacena opcionalmente en un formato protegido para evitar el acceso no autorizado. También se acompaña de una cadena de certificados para la clave pública correspondiente.

     

Las claves privadas y las cadenas de certificados son utilizadas por una entidad dada para la auto-autenticación. Las aplicaciones para esta autenticación incluyen organizaciones de distribución de software que firman archivos JAR como parte de la liberación y / o el software de licencia.

     

KeyStore.SecretKeyEntry   Este tipo de entrada contiene una clave secreta criptográfica, que se almacena opcionalmente en un formato protegido para evitar el acceso no autorizado.

     

KeyStore.TrustedCertificateEntry   Este tipo de entrada contiene un único certificado de clave pública que pertenece a otra parte. Se denomina certificado de confianza porque el propietario del almacén de claves confía en que la clave pública en el certificado pertenece a la identidad identificada por el sujeto (propietario) del certificado.

     

Este tipo de entrada se puede usar para autenticar a otras partes.

    
respondido por el Julian Knight 23.01.2016 - 17:03
fuente

Lea otras preguntas en las etiquetas