/ / ¿Cómo funcionan los autenticadores móviles? PHP, autenticación, móvil, seguridad

¿Cómo funcionan los autenticadores móviles? PHP, autenticación, móvil, seguridad

Me preguntaba cómo funcionan los autenticadores móviles (como Battle.net, grieta, algunos bancos tienen uno, etc.), así que puedo crear uno para mi propio sitio (solo por diversión).

Entiendo lo básico: El autenticador tiene un código relacionado con el teléfono y un código relacionado con el sitio web. Los usuarios ingresan el código del teléfono en el sitio web. Luego puede generar un token relacionado (usando el código del teléfono y el sitio web).

Sólo me pregunto cómo Se crean las fichas. ¿Hay un algoritmo estándar para esto? ¿Cómo funciona el algoritmo? ¿Alguna biblioteca existente de PHP que pueda hacer algo como esto (como ejemplo)?

Respuestas

6 para la respuesta № 1

Mira esto Google Authenticator. Ya hay aplicaciones para iPhone, Android y Blackberry para eso y es un protocolo establecido.

Lo han implementado como un módulo PAM de código abierto que puede ser capaz de usar con el PECL PAM paquete.

Hay un versión PHP pura pero no he usado eso, así que no puedo responder por ello.

los especulación no es ese complejo, por lo que probablemente podría implementarlo usted mismo, especialmente si convirtió el módulo C. La especificación enlazada allí explica su funcionamiento con todo detalle.

Editar: Supongo que para responder a la pregunta original, que "sun RFC, por lo que está algo estandarizado, es una especificación completamente abierta y las herramientas para usarlo son de código abierto. Los protocolos son conocidos como HOTP y TOTP. El primero es HMAC basado en un contador (por lo tanto, se usa la contraseña nth), mientras que el segundo se basa en el tiempo (por lo tanto, la contraseña alterna cada 30 segundos).


1 para la respuesta № 2

Con respecto al autenticador de Blizzad Battle.Net, puede encontrar una implementación de código abierto en PHP: https://github.com/krtek4/php-bma

La implementación se utiliza para proporcionar un servicio de autenticación en línea para Battle.Net: https://authenticator.me

Si quieres hacer algo así para tusitio web, es bastante simple. Lo único que se comparte entre el servidor y la parte del cliente es el secreto generado por el servidor. Por lo tanto, cuando un cliente solicita un nuevo secreto, simplemente guárdelo y podrá calcular el código. En cualquier momento para comparar con lo que se te envía.


0 para la respuesta № 3

Implementé esto una vez. Utilizo una clave de 4 dígitos con un subconjunto de caracteres (observe que se eliminan los caracteres potencialmente confusos como 0oO y l1L. Usé 4 caracteres porque el espacio potencial de 4 dígitos del conjunto de caracteres era mayor que los 6 dígitos de una clave RSA.

De todos modos, dejo que el usuario inicie sesión con su nombre de usuario.y contraseña. Si eso es correcto, genere una clave y envíela al teléfono, guárdela en la sesión y muestre al usuario la página siguiente, que requiere que se ingrese la clave. El usuario obtiene la clave de 4 dígitos de su teléfono y la ingresa en la página. A continuación, compruebe lo que ingresaron en la clave guardada de la sesión y ahí está.

Algunas características útiles para tener: haga que la clave caduque después de unos minutos, pero lo suficiente como para que los retrasos en los mensajes de texto no lo hagan imposible. Hágalo vencer después de varios intentos. Entregue a los usuarios un enlace para reenviar la clave o para enviar una nueva clave.

//pick a random 4 digit string
$chars = "abcdefghjkrstwxyzABCDEFGHJKRSTWXYZ23456789";
$key = "";
for($i=0;$i<4;$i++){
//here, rand is used, but any generator could be used
//to choose the characters.
$key .= $chars[rand(0,strlen($chars)-1)];
}
//save it to the session
$_SESSION["test"]["KEY"] = $key;

0 para la respuesta № 4

Si fuera yo, seguiría generando un hash basado en el hash utilizado anteriormente y en un nonce común, lo difícil sería mantener los dos sistemas sincronizados, p. Ej.

<?php

class otp {
var $salt;
var $previous_hash;
var $user_id;

function __construct($user_id)
{
$this->user_id=$user_id;
list($this->$salt, $this->$previous_hash)
=unserialize(file_get_contents(BASE_PATH . $user_id));
}
function authenticate($submitted_otp)
{
if (!$this->salt) {
// user does not exist
return false;
}
$new_hash=$this->previous_hash;
// allow for the sequence to get out of sync by 5 steps....
for ($x=0; $x<5; $x++) {
$new_hash=md5($this->salt, $new_hash);
if ($new_hash===$submitted_otp) {
$this->update_token($new_hash);
return true;
}
}
// none of the next N iterations of the local password match
return false;
}
function create_user($user_id, $salt, $init_hash)
{
return file_put_contents(BASE_PATH . $user_id, array($salt, $init_hash));
}
function update_token($new_hash)
{
file_put_contents(BASE_PATH . $user_id, array($this->salt, $new_hash));
}
}

Por supuesto, en la práctica, probablemente no querrá utilizar un hash md5 de 32 caracteres (solo, digamos, los primeros 6 caracteres y aplicar la limpieza, como cambiar la "S" a "5", etc.).