Estoy trabajando en una aplicación Node.js que requiere que el usuario ingrese sus claves API desde un servicio de terceros (el servicio no permite iniciar sesión a través de oauth). En este momento, los estoy almacenando en un archivo .env, por lo que debe ingresarse en la configuración. Me gustaría que el usuario pueda configurar las claves una vez en la interfaz de usuario (con una contraseña) y luego almacenarlas de manera persistente, de modo que cuando salga de la aplicación y reinicie nuevamente, las claves aún estarán allí. ¿Cómo haría esto? ¿Cifro las claves y las almaceno en una base de datos? ¿Hay otros métodos?
En general, esto es demasiado riesgo tanto para sus usuarios como para usted como proveedor de servicios. Si estas son claves API valiosas que desea almacenar, su servicio se convierte en un buen objetivo. Como también notó, esto es para lo que se inventó Oauth.
Si aún decide hacer esto, puede cambiar algo de ux por más seguridad. Definitivamente, debe cifrar las claves de API, pero la pregunta siempre es dónde almacenar las claves de cifrado para que realmente tenga sentido.
Piense en cómo un atacante podría apoderarse de estas claves API (las amenazas), y eso ayudará a encontrar las protecciones adecuadas (mitigaciones de esas amenazas).
Por ejemplo, un atacante podría acceder a la base de datos directamente o sin conexión, como desde una copia de seguridad o a través de un servidor de base de datos comprometido. Para esto, el cifrado estándar en reposo proporcionado por su dbms es bueno, especialmente si usa algo como AWS y KMS para almacenar las claves de cifrado. Entonces necesita cifrado en reposo, pero eso no es suficiente.
Un atacante también podría comprometer su aplicación, por lo que el cifrado transparente no ayuda. Por ejemplo, puede cifrar sus campos confidenciales (es decir, las claves de API) en el nivel de la aplicación, con claves únicas asociadas con cada usuario, almacenadas de forma segura en un servicio adecuado (como un HSM o algo como Secrets Manager en AWS). Esto aún podría permitir el acceso a un atacante, pero se está volviendo más difícil y obtiene mucho más control y auditabilidad sobre el acceso clave.
Y para ir un paso más allá, puede derivar claves de las contraseñas de sus usuarios con una función de derivación de claves adecuada (como pbkdf2 o similar), y nunca almacenarlas en una base de datos, solo en la memoria. Esto significa que los secretos de los usuarios registrados aún pueden verse comprometidos por un atacante si tienen acceso a la memoria del servidor y/o comunicaciones de red en el extremo del servidor (después de que tls finalice), pero los secretos de los usuarios sin conexión seguirán siendo seguros, porque incluso usted no tengo la clave para descifrarlos. Por supuesto, esto solo funciona si solo necesita acceder a sus claves de API siempre que estén presentes.