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:
- 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.
- 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?
- Expone la clave en un archivo que debe estar protegido de alguna manera.
- 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
- 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)