¿Está bien que el secreto de la API se almacene en texto sin formato o que se pueda descifrar?

31

¿No se considera API keys como nombres de usuario y API secrets se consideran contraseñas? ¿Por qué los servidores de API como Amazon Web Services le permiten ver su secreto de API en texto sin formato? Me hace pensar que lo almacenan en texto plano o al menos en un formato capaz de descifrar.

¿No es mejor que los secretos de la API se traten como contraseñas que debe escribir para crear y luego rellenar en la base de datos en lugar de entregarse en texto sin formato? Si, por algún motivo, su base de datos secreta API se ve comprometida, abrirá fácilmente las compuertas de inundación para muchas aplicaciones que utilizan su API. Sin embargo, si se hizo un hash de manera no descifrable, no todo se perderá fácilmente.

    
pregunta IMB 12.08.2012 - 21:11
fuente

8 respuestas

17

No. Las claves API deben almacenarse en texto sin cifrar.

No son contraseñas: son claves criptográficas. Estas claves se usan para cosas como la autenticación de solicitudes (usando SHA1-HMAC). El servidor necesita conocer la clave criptográfica para aplicar los algoritmos criptográficos.

Por lo tanto, la clave API debe almacenarse en texto claro en el servidor. Si el servidor almacenaba solo un hash de la clave API, no podría verificar la autenticidad de los mensajes del cliente ni autenticar los mensajes enviados al cliente.

    
respondido por el D.W. 13.08.2012 - 08:28
fuente
13

Hashing no es almacenamiento; destruye irreversiblemente los datos. Podemos evitar el "hashing" de contraseña de llamada porque, cuando realmente necesitamos la contraseña, tenemos un operador humano para escribirla. De hecho, cuando tenemos la contraseña no almacenamos la contraseña, sino solo un token. suficiente para verificar la contraseña introducida.

Una clave de API debe almacenarse de tal manera que pueda ser utilizada de nuevo de una manera desatendida . El servidor realmente debe almacenar , en lugar de solo recordar un fantasma, porque necesita la clave original para acceder a la API.

    
respondido por el Tom Leek 13.08.2012 - 13:27
fuente
8

Si bien sería más seguro agrupar los tokens de la API, presenta un problema de usabilidad: los tokens son largos y aleatorios, y deberían ser informados al usuario solo una vez antes del hashing. Esto hace que sea un poco difícil asegurarlos con un hash.

Mi sugerencia para un escenario seguro sería la siguiente:

  1. Genere un valor aleatorio salt y almacénelo en la base de datos. Esta sal no debe ser igual a la sal de la contraseña del usuario.
  2. Tome la contraseña de texto simple del usuario y calcule KDF(password, salt) , donde KDF es una función de derivación de claves como bcrypt. Llame al valor resultante k .
  3. Genera una clave API.
  4. Cifre el valor de la clave API con AES, utilizando k como clave, y almacene el texto cifrado en la base de datos.
  5. Descartar la clave de la API de texto sin formato y k .

Cuando el usuario inicia sesión, la aplicación web conoce su contraseña y la utiliza para calcular k , que luego se usa para descifrar la clave API y mostrarla a ellos.

Cuando el usuario desea utilizar la API, debe enviar k , así como la clave de la API de texto sin formato, sobre SSL. La aplicación web puede luego descifrar el valor de la clave API almacenada usando k y compararla con la clave API dada. Si coinciden, es válido. Esto permite el uso de la clave API sin que la aplicación necesite almacenar la contraseña del usuario.

Si un atacante infringe la base de datos, debe descifrar la contraseña del usuario para calcular k .

    
respondido por el Polynomial 13.08.2012 - 00:42
fuente
6

Parece que hay un poco de confusión aquí y otros lugares , así que estoy agregando esta respuesta con la esperanza de que aclare la situación para otros usuarios.

Se pueden usar dos tipos de secretos de API.

El caso de uso que analizan la mayoría de las respuestas en esta página es una clave secreta que se utiliza para firmar y verificar mensajes utilizando un algoritmo como HMAC. En este caso, tanto el cliente como la API necesitan el valor real de la clave para crear una firma del mensaje. El servidor luego compara la firma que generó con la firma que el cliente envió y puede verificar el mensaje. Como se mencionó anteriormente, si la clave original no es reproducible en el servidor, esto no puede funcionar. Después de compartir inicialmente la clave con el cliente (a través de un canal encriptado), la clave no necesita ser transmitida nuevamente entre el cliente y el servidor.

El otro secreto del cliente API común es simplemente una credencial secreta (como puede ver en una solicitud de token de acceso OAuth2 típica). Esta credencial se transmite en cada solicitud y, por lo tanto, solo se debe transmitir a través de un canal cifrado (como HTTPS). En este caso, el servidor solo necesita retener suficiente información para verificar que el valor secreto proporcionado por el cliente es correcto, por lo que el secreto puede y debe estar incluido. En este caso, el secreto está actuando efectivamente como una contraseña, por lo que se deben tomar las mismas precauciones.

Descargo de responsabilidad: no soy un investigador de seguridad, y debe hacer más investigación sobre este y cualquier otro tema antes de seguir ciegamente cualquier consejo sobre este StackExchange.

tl; dr La conclusión más importante es que diferentes API pueden usar el secreto de diferentes maneras. Es importante entender cómo su API utiliza el secreto del cliente para evaluar las mejores prácticas para almacenarlo.

    
respondido por el Nick Sloan 12.07.2017 - 19:06
fuente
4

Poner mis propios dos centavos debido a un problema que aún no se ha mencionado. En particular, estoy de acuerdo con lo que dijo @NickSloan, pero con una advertencia más.

Hay una diferencia más importante entre una clave API y una contraseña. Las claves API son únicas para su sitio. La parte que hace que la seguridad de la contraseña sea tan importante es compartir la contraseña. Si alguien retiene la contraseña que un usuario guardó en su sitio, no solo se compromete su sitio: son todos los otros sitios para los que el usuario usó esa contraseña (y correo electrónico / nombre de usuario). Muchas personas reutilizan contraseñas en sitios críticos: bancos, redes sociales, correo electrónico, etc., lo que significa que la buena seguridad de las contraseñas no se trata tanto de proteger el acceso a su sitio como de proteger a sus usuarios en otros sitios. No podemos obligar a los usuarios a mejorar la seguridad, por lo que debemos asumir lo peor y tomar medidas adicionales para proteger su propia privacidad.

Una clave API es un escenario completamente diferente porque es exclusivo de su sitio. Como resultado, si es robado, el atacante obtiene acceso a su sitio, pero no gana nada que pueda utilizar contra el banco / correo electrónico / etc de esa persona. Esto significa que el nivel de riesgo para las claves API es en realidad más bajo que el de las contraseñas. No están exactamente en el mismo parque de pelota: las claves API son más similares a los identificadores de sesión que a las contraseñas.

Comprender que estos son más parecidos a los identificadores de sesión que a las contraseñas proporciona información práctica sobre cómo proteger adecuadamente estas claves. Tenga en cuenta que la siguiente discusión es aplicable a las Claves de la API para cosas como las credenciales de OAuth y no a las credenciales de encriptación (como lo explica @NickSloan en su respuesta).

Las amenazas más grandes para las contraseñas son los ataques de phishing y las bases de datos pirateadas, por lo que las almacenamos con hash en nuestras bases de datos. Las amenazas más grandes para las claves de API son las mismas que para las claves de sesión: debilidades en aplicaciones front-end como vulnerabilidades XSS, MIM y similares. Es importante tener en cuenta que la aplicación de front-end necesita la contraseña en forma no cifrada, por lo que el hashing de la clave API no le gana nada cuando la persona que es más probable que la roben la necesita en texto simple.

En su lugar, protege un identificador de sesión (o token de OAuth, o clave de API específica del cliente) principalmente mediante el seguimiento del cliente. Si un identificador de sesión es robado a través de XSS u otro medio del cliente, un resultado típico es que el atacante use ese identificador en un dispositivo nuevo. Eso significa que, de repente, verá que una clave antigua aparece con un nuevo agente de usuario. Tal cambio es fácil de detectar y corregir: invalida inmediatamente todas las claves API. Especialmente en el caso de las solicitudes de OAuth, esto es muy sencillo para el usuario: simplemente vuelven a iniciar sesión y obtienen una nueva, mientras que alguien que solo robó la llave (y no tiene la contraseña) regresa a la mesa de dibujo .

Esta es una medida de defensa lo suficientemente común como para que un pirata informático más inteligente también intente registrar el agente de usuario asociado con la clave robada y lo utilice en todas las solicitudes futuras, pero aún puede ver fácilmente que ocurre algo sospechoso cuando el mismo usuario tiene solicitudes procedentes de múltiples direcciones IP. Como todo lo demás en el mundo, esto puede ser un poco como un juego del gato y el ratón, pero hay algunos puntos importantes:

  1. Una clave API / OAuth Token / ID de sesión es realmente una forma de recordar a un usuario en un dispositivo en particular, para que no tengan que poner su contraseña en cada página. Como resultado, en caso de duda, puede eliminar todas las claves autorizadas y obligar al usuario a iniciar sesión nuevamente.
  2. En los tres casos, dado que perder Key / Token / ID hace que una cuenta se vea comprometida, es importante tener cierta seguridad activa en estas cosas y detectar / responder si ocurre algo sospechoso. Si alguna vez ha recibido avisos de facebook / google / etc sobre alguien que intenta iniciar sesión en su cuenta desde México, es porque un tipo de seguridad en algún lugar está haciendo su trabajo correctamente.
  3. Los vectores de ataque principales para las Claves / Fichas / Identificaciones son diferentes a los de las contraseñas. Es posible que aún desee incluirlos en su base de datos (nuevamente, no estamos hablando de credenciales de encriptación que deben estar en texto sin formato), pero no puede simplemente incluirlas en su base de datos y llamarse seguro. Debes asegurarte y asegurarlos contra una nueva gama de vectores de ataque. Si los considera solo como contraseñas, perderá algunas partes importantes del panorama general.
respondido por el Conor Mancone 12.07.2017 - 19:45
fuente
2

Una de las principales razones por las que las contraseñas se hacen con un hash antes de almacenarlas, es para protegerse contra un atacante que obtiene un acceso de solo lectura a la base de datos . De esta manera, si un atacante se apodera de la lista de credenciales de inicio de sesión, aún no podrá usarlas directamente porque las contraseñas están hash / salted.

Y este no es solo un problema teórico que intentamos resolver aquí, este tipo de ataques realmente ocurren ( incluyendo a los principales actores de la industria ), y el hashing adecuado ayuda a mitigar el impacto de un ataque.

Si está permitiendo que los usuarios se autentiquen utilizando un secreto de API, entonces el secreto de la API se ha convertido efectivamente en una contraseña , por lo tanto, desde un punto de vista de seguridad, deberían tener los mismos mecanismos de protección que tienen las contraseñas normales. / p>

Amazon mismo ahora no permite recuperar el secreto de la API . Si lo olvidas, debes solicitar uno nuevo.

    
respondido por el Pedro Rodrigues 28.02.2017 - 11:38
fuente
0

No, no está bien para algún tipo de servicio.

Implementación

1. Al conectarse el usuario con la contraseña de inicio de sesión, genere una clave derivada de su contraseña para cifrar los datos de este usuario y mantenerla en una sesión en el servidor.

De esa manera, cada usuario tendrá una clave única. Esta clave derivada no debe ser reversible, este es el punto principal. El uso de hash_mac u otro método de hashing con sal y / o clave maestra lo permitirá.

2. Utilice esta clave para cifrar el Secreto API generado usando AES 256 con un iv aleatorio para cada usuario.

O

2.bis Use esta clave para generar la clave de encriptación real en el último momento y encriptar el método API de la misma manera que en 2. para evitar contraseñas flotantes en la memoria.

3. Almacene el iv en la base de datos junto con el ID de usuario y el ID de la aplicación en una tabla dedicada

4. Almacene el secreto de la API cifrada en la base de datos en la tabla correspondiente.

Usuario

Ahora, cuando el usuario se conecta a su panel de control, puede recrear la clave, buscar el iv, descifrar el Secreto de API para este usuario y mostrarlo en texto claro. También muestra la clave y solicita ambas al hacer una llamada API para que pueda verificar el Secreto de la aplicación.

Si desea evitar mostrar la clave y no tener que solicitarla en una llamada a la API, también puede usar el mismo método de autenticación para iniciar sesión. Lo que significa que puede crear otra tabla para almacenar una clave / sal aleatoria para cada aplicación cliente y almacenar una versión hash_mac del Secreto de API. Por lo tanto, solo se requieren el ID de API y el Secreto de API para autenticar la solicitud de API. pero es más trabajo.

Nota

Esto es prácticamente lo mismo que la respuesta @Polynomial

De esta manera es muy difícil para alguien que piratee su servidor y su base de datos robar las credenciales de sus usuarios y hacer llamadas a API en su nombre. Ahora puede evaluar que si una solicitud ha sido aceptada por un cliente API, es el cliente correcto o si es su pérdida.

Si el usuario pierde su contraseña, a continuación, regenera un nuevo API Secret y clave a partir de su nueva contraseña.

    
respondido por el Nicolas Manzini 29.11.2015 - 12:10
fuente
-2

Bueno, en este backend también puede aprovisionar el servidor y leer todos los datos de todos modos. Debe asegurarse de que nadie pueda acceder a su backend, de lo contrario, leerá todos sus datos a la vez, incluidas las copias de seguridad.

    
respondido por el Andrew Smith 12.08.2012 - 21:26
fuente

Lea otras preguntas en las etiquetas