Pregunta ¿Cómo aceptar la autenticación en una API web sin SSL?


Estoy construyendo una API web muy similar a lo que Desbordamiento de pila proporcionar.

Sin embargo, en mi caso, la seguridad es importante ya que los datos son privados.

  • Debo usar HTTP.
  • No puedo usar SSL.

¿Qué solución (es) me recomiendan?

EDITAR: autenticación! = cifrado


10
2017-12-22 13:31


origen


Respuestas:


Casi todas las API públicas funcionan pasando un token de autenticación para cada solicitud web.

Este token generalmente se asigna de una de dos formas.

En primer lugar, algún otro mecanismo (por lo general, iniciar sesión en un sitio web) permitirá al desarrollador recuperar un token permanente para usar en su aplicación particular.

La otra forma es proporcionar un token temporal a pedido. Por lo general, tiene un método web en el que le transfieren un nombre de usuario / contraseña y devuelve un token de uso limitado en función de si está autenticado y autorizado para realizar cualquier acción de API.

Después de que el desarrollador tiene el token, lo pasan como un parámetro a cada elemento web que expone. Sus métodos primero validarán el token antes de realizar la acción.

Como nota al margen, el comentario que hizo sobre "la seguridad es importante" obviamente no es cierto. Si fuera entonces, harías esto a través de SSL.

Ni siquiera consideraría esto como una seguridad "mínima" en ningún contexto, ya que solo proporciona una falsa creencia de que tiene algún tipo de seguridad en su lugar. Como señaló Piskvor, cualquier persona con un mínimo de interés podría escuchar o romper esto de alguna manera.


17
2017-12-22 22:39



Antes que nada, sugiero que lea este excelente artículo: http://piwik.org/blog/2008/01/how-to-design-an-api-best-practises-concepts-technical-aspects/

La solución es muy simple. Es una combinación de Flickr como API (token based) y el método de autenticación utilizado por el paiement gateway Uso (altamente seguro), pero con una contraseña / sal privada en su lugar.

Para evitar que usuarios no autorizados utilicen la API sin tener que enviar la contraseña en la solicitud (en mi caso, en claro ya que no hay SSL), deben agregar una firma eso consistirá en un Hash MD5 de una concatenación de valores privados y públicos:

  • Bien conocidos valores, como el nombre de usuario o incluso la ruta API
  • Una frase de acceso de usuario
  • Un código único generado por el usuario (se puede usar solo una vez)

Si lo solicitamos / api / ruta / y la frase de contraseña es kdf8 * s @, la firma será la siguiente:

string uniqueCode = Guid.NewGuid().ToString();
string signature = MD5.Compute("/api/route/kdf8*s@" + ticks);

La URL de la solicitud HTTP será entonces:

string requestUrl = 
     string.Format("http://example.org/api/route/?code={0}&sign={1}", uniqueCode, signature);

Del lado del servidor, deberá evitar cualquier solicitud nueva con el mismo código único. Evitar que cualquier atacante simplemente reutilice la misma URL para su beneficio. Cuál era la situación que quería evitar.

Como no quería almacenar el código que usaba el consumidor API, decidí reemplazarlo por un garrapatas. Ticks representa el número de intervalos de 100 nanosegundos que han transcurrido desde las 12:00:00 de la medianoche del 1 de enero de 0001.

En el lado del servidor, solo acepto ticks (timestamp) con una tolerancia de + -3 minutos (en caso de que el cliente y el servidor no estén sincronizados en el tiempo). Lo que significa que el atacante potencial podrá usar eso ventana para reutilizar la URL pero no de forma permanente. La seguridad se reduce un poco, pero sigue siendo lo suficientemente buena para mi caso.


16
2017-12-25 20:08



Respuesta corta: si se supone que se puede utilizar a través de clientes habituales (solicitudes de navegador / AJAX), está jodido.

Siempre que utilice un transporte no encriptado, un atacante podría eliminar cualquier tipo de código de encriptación a través de un ataque MITM. Incluso SSL no proporciona una seguridad perfecta, pero el HTTP simple requeriría algunas extensiones específicas fuera de la página.

HTTP proporciona solo transporte: sin identificación segura, sin autenticación segura y sin autorización segura.

Ejemplo de agujero de seguridad: una simple página HTTP:

<script src="http://example.com/js/superstrongencryption.js"></script>
<script>
  encryptEverything();
</script>

Esto puede parecer seguro, pero tiene un defecto importante: no tiene ninguna garantía, en absoluto, que en realidad estás cargando el archivo superstrongencryption.js lo estás solicitando Con HTTP simple, enviarás una solicitud algun ladoy alguna cosa Vuelve. No hay forma de verificar que proviene realmente de example.com, ni tiene ninguna forma de verificar que en realidad es el archivo correcto (y no solo function encryptEverything(){return true})

Dicho esto, en teoría podría construir algo muy parecido a SSL en sus solicitudes y respuestas HTTP: encriptar criptográficamente y firmar cada solicitud, lo mismo con cada respuesta. Sin embargo, necesitará escribir un cliente especial (más el código del lado del servidor, por supuesto): no funcionará con los navegadores estándar.


6
2017-12-22 13:38



Autenticación HTTP proporciona una muy buena autenticación. Todas las bibliotecas de clientes HTTP que he usado lo soportan. No proporciona ningún cifrado en absoluto.


1
2017-12-22 20:41