Foro de elhacker.net

Seguridad Informática => Criptografía => Mensaje iniciado por: matake en 20 Noviembre 2016, 23:58 pm



Título: Algoritmo inscripcion autenticacion
Publicado por: matake en 20 Noviembre 2016, 23:58 pm
Hola,

Después de muchísimas vueltas y reflexionando sobre los consejos que me dio kub0x en mis post anteriores  he pensado en el siguiente algoritmo de autenticación:

Inscripción:
  Cliente:

    - Escoge un nombre usuario
    - Proporciona su numero de teléfono móvil
    - Envía estos datos


 Servidor:
    - Crea una tarjeta de coordenadas con 20 de coordenadas aleatorias (como
      sugirió kub0x números entre 10.000 y 99.999)
          A      B     C    D
      1  --     --    --    --
      2  --     --    --    --
      3  --     --    --    --
      4  --     --    --    --
      5  --     --    --    --
           Escoge 3 de ellas al azar.
      Ej: A3,C5 y D4 (12345, 99876, 68872 )
      
      Suma los numeros pertenecientes a cada coordenada entre si
      A3 = 12345 = 1+2+3+4+5 = 15
      C5 = 99876 = 9+9+8+7+6 = 39
      D4 = 68872 = 6+8+8+7+2 = 31
      
      Concatena estos resultados en una variable "$base"
      $base = "153931";
      
    - Escoge 1 color al azar de los 7 básicos del arco iris
   
    - A cada color corresponde un array aleatorio de números   
   Ej: $rojo = [4,0,3,1,2,5] donde cada elemento del array representara la posición
       dentro de "$base"
      
    - Emplea este array como algoritmo para alargar la "base" para emplearlo como
       passphrase
      
   Ej: $rojo[0] = 4 representara el quinto elemento de $base (empezando con 1)
        que seria en este caso el 3
   entonces hace 153931 ^ 3 = 3647356987253491 y lo concatena como string en
        una variable $passphrase
      etc ... etc ver ejemplo PHP abajo      
      En el ejemplo he utilizado potencias ... pero se podrá usar lo que uno quiere
      
Código
  1. $passphrase = '';
  2. $base = "153931";
  3. $algoritmo = [4,0,3,1,2,5]; //$rojo
  4.  
  5. foreach($algoritmo as $posicion){
  6. if($base[$posicion] == "1"){
  7. $exponent = "10"; //para no dejarlo a la potencia 1
  8. }else{
  9. $exponent = $base[$posicion];
  10. }
  11. $passphrase .= bcpow($base,$exponent);
  12. }
  13.  
  14. //lo que daría como resultado la passphrase siguiente:
  15. //36473569872534917468973308479888166911376979002445509842001282099801485215668609954341030161369639802607001968497718642322204407729767913865136473569872534917468973308479888166911376979002445509842001282099801
      
      
      Esta sera la passphrase "P"   para ser empleada en el cifrado simétrico    
      36473569872534917468973308479888166911376979002445509842001282099801485215668609954341030161369639802607001968497718642322204407729767913865136473569872534917468973308479888166911376979002445509842001282099801
      
        Envía al usuario por SMS la tarjeta de coordenadas + La referencia a una de las tres coordenadas empleadas mas arriba ej: D3 y el color ej: rojo (verán mas abajo en la autenticación porque D3 y no D4 que se utilizo realmente )
      
   Lo que el usuario tendrá que memorar seria "D3" y "rojo" ... la tarjeta de coordenadas la imprime o la apunte (de todos modos aconsejado que la borre del móvil)
      
   En el servidor se guarda:
   Un hash (sha3) sobre la passphrase "P"
   La tarjeta de coordenadas y los datos del usuario cifrados (simétrico) usando la passphrase "P"
   Dos referencias a las coordenadas de la tajeta Ej: A3 y D4 (para este caso)
   Y un numero de referencia de 1 a 20  en vez de la tercera coordenada ej: 1 (verán mas abajo en la autenticación porque 1 en el caso actual)
   Guarda también el color que escogió (o un hash)
      
   Enviara al administrador la passphrase P cifrada con otro algoritmo (parecido  al de arriba) y este lo guardara en una maquina sin conexión a internet + otras medidas de seguridad (para comprobar manualmente en caso de perdida).      
      
      
      
      
Autenticacion:
   Cliente:

    - Introduce su nombre usuario
   
   Servidor:
    - Si el usuario es correcto    
    - Le pide escoger su color (que memorizo)
    - Si el color es correcto le manda el algoritmo utilizado Ej: $rojo = [4,0,3,1,2,5] ,
           las dos coordenadas que se usaron para construir la passphrase mas un numero explicado mas abajo
    - S le pide que sume de memoria (o en papel ideal seria que si lo suma en una calculadora que no sea la del  aparato con el que se esta conectando a internet)
   Normalmente no seria tan difícil sumar 5 números de memoria
   y apuntar solo el resultado en la casilla correspondiente (y no el valor de la coordenada)
   Ej:
   A3 = 12345 = 1+2+3+4+5 = 15
   C5 = 99876 = 9+9+8+7+6 = 39
      
   Para la tercera referencia (Que se supone que memorizo al inscribirse y recibio D3 en vez de D4 que se utilizo realmente )  solo recibe el numero 1
   Entonces se le pide a que al la coordenada que memorizo (D3) le suma 1 (en este caso ) lo que le dara D4 y que haga la suma como en las de arriba y apunte el resultado en la casilla
      
   secreto +1 = D3 +1 = D4 = 68872 = 6+8+8+7+2 = 31   
       (llamaremos secreto a la referencia D3 que el usuario tendra que memorizar)
      
   Si el secreto era D5, entonces D6 no existe (porque solo hay 20 coordenadas) y el siguiente sera A1 (algo parecido a los módulos) empezar desde el principio
   o si el numero que recibe el usuario sera mas grande por ej. 10 y el secreto es D3 entonces la coordenada correcta seria B3
   O sea si contando desde su secreto el nr que recibe llega al final D5 ... continua con el A1 A2 etc
       Ej:
       D5 + 1   = A1
       D3 + 6   = A3
       D3 + 10 = B3 ... etc

      
   El resto se hace automáticamente en el lado cliente y se regenera la passphrase P
   la cual se puede primero comprobar con su hash y si esto es ok se autentifica y se  desencriptan sus datos
      
   Si la autenticación es OK el servidor genera otros credenciales para la siguiente autenticación
   También controla la sesión en curso con combinaciones de tokens + tiempo + la passphrase correcta que no se utilizara otra vez para login
      
      
      
Resumiendo:


   - El usuario solo tendrá que memorar Un color (ej: rojo) y dos dígitos  ej: D3 (y no el contenido de la coordenada.  Solo la referencia)
   - Si alguien intenta mandar su usuario y su color pero no llega autenticarse se le notificara al usuario y si las dos coordenadas pedidas son correctas, (pero no la secreta) se pregunta al usuario y si no ha sido el, se le cambia la tarjeta de coordenadas obligatorio
   - La passphrase no se guarda en ningún lado (eventualmente el administrador las guarda en otra maquina con otro cifrado y sin conexión a internet para recuperación y comprobación de los datos manualmente en caso de perdida)
   Se le puede pedir al usuario al principio si acepta esto ... pero si no acepta ... pierde todo si se pierde la tarjeta de coordenadas o se olvida la que tiene como secreta
   - No revela los números de las coordenadas que tiene
   - La coordenada que tiene secreta siempre es otra (Aunque el memoriza la misma siempre)
   - Aunque se le robe la tarjeta de coordenadas no se podrá saber cual es la secreta (bueno ... digamos ... bastante difícil)
   - Siempre que se ha conectado de otra maquina se le avisa
   - No habrán nunca dos sesiones permitidas al mismo tiempo
   - Esto si, tiene que hacer unas sumas simples de memoria ( Eso le tendrá el cerebro entrenado :D )
   
   
   
   Bueno dicho esto, como muchas cosas, en teoría parece bien pero con mis escasos conocimientos de matemática no se si esto seria un sistema fiable por esto espero sus opiniones
   
   
   Cada paso se puede complicar de varias formas pero espero primero vuestras opiniones, criticas , mejoras ,puntos debiles etc.
   
   Como duda mas grande que tengo por ahora: ¿es la passphrase P fuerte desde el punto de vista criptografico ? (se pasa tambien por pbkdf2 )
   He olvidado decir :
   Para el cifrado simétrico he pensado en el AES-256 CBC siguiendo los consejos de @kub0x:
   Salt e IV aleatorios,
   pbkdf2 con iteraciones diferentes por cada algoritmo, usuario y autentificacion para la  "passphrase" ,
   cifrado AES-256 CBC padding: Pkcs7 ,
   hmac para el control de integridad
   
   
   Saludos y espero vuestras opiniones
      
      
      
      
      
      
      


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 21 Noviembre 2016, 19:10 pm
Buenas matake, bonito problema combinatorial, recuerdo cuando empecé a interesarme por la crypto, un amigo cercano me dijo: Déjaselo a los matemáticos, y desde ese día me puse la meta de comprender la matemática subyacente así como estudiar nuevos campos relacionados con la crypto. Lo que quiero decir es que proponer es fácil, pero la mayoría de veces romperlo (criptoanálisis) por tus medios no lo es. Hoy día sigo peleando con ese gigante pero ya le he ganado unas cuantas batallas.

Suponemos que conocemos las credenciales usuario/password del usuario en cuestión. Por lo tanto nos quedan tres incógnitas: color y tres coordenadas de la tarjeta. Suponiendo que el intercambio está cifrado por TLS (HTTPS) poco podemos averiguar de ahí, por lo tanto:

Primero debemos de hallar el color. Son 7 colores antes de proceder al cálculo de la base que nos deja P. Probabilidad \frac{1}{7}. En una tirada tenemos el 14% de hallarlo. En el peor de los casos 7 intentos bastarían para hallar el color asignado a ese usuario. El atacante sabe que estás mapeando números de 5 digitos (10.000 hasta 99.999) a un espacio de 2 dígitos con tamaño 44 (1 hasta 45). ¿Por qué? -> Coge el máximo (99.999) haz la suma digital y obtienes 9*5=45. Ten en cuenta que la suma digital de dos números capicúa, permutados y al reverso es la misma. Al mapeo lineal de 5 a 2 dígitos se le conoce como homomorfismo matemático.

Ahora que sabemos el color procedemos a la parte "complicada", hallar la suma digital de las tres coordenadas desconocidas por el atacante. Trabajaré con las coordenadas que diste, A3,D4,C5.

Si la suma digital de varias coordenadas es la misma: SD(A3)=SD(D4)... por lo tanto nos queda una variación con repeticion de 44 elementos (suma digital mínima->1 - suma dígital máxima 45) tomados en 3 (son 3 coordenadas) VR(44,3) = 44^{3}= 84184  intentos en el peor de los casos para hallar la base. Como ya sabemos el color, es trivial calcular P haciendo exponenciales a la base tomando sus dígitos como exponente dependiendo de la posición del algoritmo del color.

Si la suma digital de todas las coordenadas son distintas: SD(A3)!=SD(D4)... Pasamos de la VR a la variación estándar (V) \frac{44!}{3! \cdot 44!}= 79464  intentos para hallar la base en el peor de los casos.

No todo acaba aquí. Pensándolo bien, darle al usuario la tarjeta de 20 elementos con cinco cifras es lo mismo que darle la tarjeta con la suma digital de esos 20 elementos.

Posibles mejoras:

- El color no es más que una permutación del máximo de dígitos de la base. En este caso son máximo 2 dígitos por coordenada, la base son 3 coordenadas = 2*3 = 6 dígitos tiene la base como máximo. El color sería P_{6}=6!= 720 posibles "colores" o vectores de posición. Si el atacante supiera la base pero no el vector permutación, tendria P, pero desordenado. La probabilidad de acertar el vector permutación ahora es infima según vaya incrementando el número de dígitos máximo de la base.
- Incrementar el espacio numérico de las coordenadas para que la suma digital sea más grande hasta que la variación estándar y la repetida queden intratables (lo desaconsejo debido a que una coordenada de 20 dígitos todo a 9's tendria una suma digital de 180 máximo. Con 1500 dígitos la suma dígital máxima seria de 13500 y ahí ya podría ser intratable con 2.4 billones de intentos para hallar la base. Quizá con estas dos modificaciones (vector permutación e incremento del espacio numérico de la suma digital) el esquema sea seguro y fuerte.

Agarre por donde lo agarre lo rompo. Añadir capas de restricción como bloquear al de 3 intentos y re-generar la tarjeta solo añade complicaciones y mala disponibilidad del servicio, ya que Internet no es una utopía y hay mucho listo suelto.

Aun así, no te desmotives. Por cierto esta pregunta reciente me recordo a tí -> https://crypto.stackexchange.com/questions/41643/having-access-to-multiple-servers-would-additional-usage-of-secret-sharing-fo

Puedes leer sobre Secure Multi-party computation (https://en.wikipedia.org/wiki/Secure_multi-party_computation) se basa en no intercambiar el secreto para establecer una veracidad sobre la autenticación. Y haciendo alusión a la introducción de mi post: estos temas dejaselos a los matemáticos ;) Para ello ya hay docenas de algoritmos para la autenticación e identificación de extremos, bien provados y que son seguros.

P.D = ¿Quizá se me haya pasado algo por alto? Dale un par de vueltas a mis argumentos y me comentas.

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 22 Noviembre 2016, 21:11 pm
Primero gracias por tu tiempo kub0x

Citar
Déjaselo a los matemáticos
 :D  Tienes toda la razon.
Citar
y desde ese día me puse la meta de comprender la matemática subyacente
Aquí también lo has clavado ... has conseguido convencerme que por aqui esta el camino para mi también.


Lo que pasa es que hasta alcanzar dicha meta ( o intentar acercarme a ella ) tengo que sobrevivir de alguna manera :D  (ademas tengo medio siglo de vida y sera mas difícil de roer huesos del gigante a esta edad)


He mirado un poco lo de Secure multi-party computation y Secure two-party computation pero no he insistido mucho viendo que se requiere un tercero de confianza (que en caso de la web supongo que seria un servidor ... ¿me equivoco?).

Inspirado en tu firma "No hay amigos, ni enemigos, lucha necia, todos contra todos" ... pues igual con los servidores en que servidor voy a tener yo 100% confianza :D


Volviendo a los matemáticos, (por esto me gustaba lo del Shamir sharing secret) pero no hay matemático que pueda hacer que al querido cliente no se le robe su secreto con un keyloger, troyano etc o en el caso de Secure multi-party computation (y otros por estilo), que no haya listo suelto (como tu decías) que no entre algún día en dicho servidor de confianza.


Así que para luchar con el gigante (como no conozco bien sus armas)... haré otro intento pero jugare sucio :D ... o sea intentare no emplear las armas del gigante (la matemática) ... y empleare las manos, los ojos, y cabeza del querido cliente ... que por cierto no va a ser contento con el trabajo que le voy a dar, pero si clama seguridad ... que venga con su contribución para poder alcanzarla !!! (¿No les parce correcto ?)


Entonces Voy a dividir el acceso de los usuarios en dos secciones:

- Una para poder trabajar, donde se usa el usuario y contraseña de toda la vida + (https TLS ... para toda la web no solo login)

- Y otra sección para datos sensibles + otras cosas que necesitan mas seguridad para la cual el cliente genere manualmente una passphrase (la P de antes) de al menos 30 digitos de longitud (y de un solo uso) pero sin revelar mucha información de su tarjeta.


   - El cliente  memoriza solo una referencia ( que le da el servidor al inscribirse ej D4 de antes )
   (¿Me explico? no memoriza el valor de la coordenada solo su referencia D4)
   
   - El servidor le manda un numero (entre -10 y +10) ej: 5 (que lo sabe desde cuando genero la ultima passphrase)
   Entonces el cliente cuenta 5 coordenadas en su tarjeta empezando desde la que tiene memorada (D4)
   Lo que le dará A3 (porque la D4 es la penúltima de su tarjeta y D5 la ultima)
   
   - Apunta a mano en un papel el valor de A3 mas los valores de sus vecinos A2 y A4 (en una sola linea)
   Ej:
   791624629153825 (15 digitos de tres coordenadas)
   
   - Ahora emplea como algoritmo los mismos dígitos que conforman el numero resultante de arriba
   Tacha el primer dígito (7 en este caso), cuenta siete dígitos adelante llegaría hasta el 6
   y apunta sus vecinos (4 y 2) o sea ahora P = 42
   Tacha el segundo dígito 9 cuenta nueve dígitos adelante, le sale 1 y apunta sus vecinos (9 y 5)
   Ahora P = 4295
   etc ... etc ...

   Si contando, supera al final continua empezando desde el principio
   Ej: para el 8 (el que esta a 3 posiciones antes del final)
   cuenta hasta el 2 (el quinto dígito desde el principio) y sus vecinos son 6 y 4
   Espero que se entiende

   - Al final P = 429596212621582171952785642712 (30 digitos)
   

  Solamente pido tu opinión (o de otros conocedores) y si ésta es también fácil de romper, ya no te molesto mas (tonterías por la cabeza me pasan millones :D )
  
  Como mejora ya me ha pasado una tontería ( en este instante ) :D ... hacer dos tarjetas esta misma numérica para el algoritmo de conteo y otra alfanumérica (mayúsculas + minúsculas + números) de donde escoger para construir la P
  
  Y otra :D ... no paro en soltar tonterías :D Para que la longitud de P no sea fija, escoger el primer dígito
  Ej actual 4 contar cuatro desde el mismo llegamos al 5 y agregamos los 5 dígitos contando desde el 5 (59621) al final de la P

  ahora P = 42959621262158217195278564271259621 (35 dígitos) y nunca no se sabrá cual es la longitud
  
  También quiero subrayar que ésta seria de un único uso (como las OTP) cada vez el servidor genera otra para la siguiente autenticación ( mejor dicho autorización, para cuando hace falta, ya que para autenticación utiliza contraseña normal)
  
  Saludos y gracias por adelantado.
  
  P.D (Perdone también por mi Castellano ... lo aprendí "a la oreja")


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 23 Noviembre 2016, 00:59 am
Buenas noches matake,

nunca es tarde para adentrarse en un tema y estudiarlo a fondo, en este caso las matemáticas, pero bueno yo soy muy joven que te voy a contar... Sobre lo de sobrevivir, lo entiendo, cada uno tenemos nuestra ocupación, y bueno, mi meta es sobrevivir de este gigante (ya me veo pidiendo en una esquina :D ).

En criptografía existe algo llamado el principio de Kerckhoff, con el cual quizá estés familiarizado. Este principio nos dicta las directrices que debe seguir un criptosistema, independientemente de su aplicación. Se puede resumir en que el sistema debe de ser conocido por el atacante pero sin revelar información subyaciente de los valores observados (fíjate en los hashes, assymetric-key crypto, symmetric-key..), debe de ser "trivial" de computar y sin apenas interacción del usuario.

Ahora, toma 5 minutos de tu tiempo y pregúntate si tu sistema cumple dichos principios:

Citar
   The system must be practically, if not mathematically, indecipherable;
    It should not require secrecy, and it should not be a problem if it falls into enemy hands;
    It must be possible to communicate and remember the key without using written notes, and correspondents must be able to change or modify it at will;
    It must be applicable to telegraph communications; (Aquí nos moveríamos en el mundo de Internet)
    It must be portable, and should not require several persons to handle or operate;
    Lastly, given the circumstances in which it is to be used, the system must be easy to use and should not be stressful to use or require its users to know and comply with a long list of rules.

Citar
Inspirado en tu firma "No hay amigos, ni enemigos, lucha necia, todos contra todos" ... pues igual con los servidores en que servidor voy a tener yo 100% confianza :D
Volviendo a los matemáticos, (por esto me gustaba lo del Shamir sharing secret) pero no hay matemático que pueda hacer que al querido cliente no se le robe su secreto con un keyloger, troyano etc o en el caso de Secure multi-party computation (y otros por estilo), que no haya listo suelto (como tu decías) que no entre algún día en dicho servidor de confianza.

La verdad, mi firma define muy bien el mundo en Internet (y en cierto punto la sociedad), siempre digo en mis respuestas que una vez ganado acceso al equipo del usuario/servidor la crypto está totalmente rota e inservible. En criptografía jugamos con otro tipo de suposiciones, simplemente nos basamos en la información que se puede obtener a través de la observación de ciphertexts, intercambio de claves etc. En cualquier esquema, si al usuario se le roba su valor privado -> GAME OVER. ¡No siempre eh! imagina que al usuario se le roba su private-key pero esta esta cifrada por AES-256-CBC, no me quedaría otra que ver en que equipos posiblemente esté almacenada, pero quizá no lo esté... Con esto quiero decir que cuanta menos información se guarde mejor.

En tu caso sucedería lo mismo, da igual cuantas veces cambies el sistema que si se le roba la tarjeta adios. Vale, el atacante no sabría el valor privado (a no ser que entre al server), pero teniendo la tarjeta del usuario, no tardaría mucho en adivinar el valor privado antes de que el usuario reporte el robo o se de cuenta de la intrusión. El factor de segunda autenticación siempre se podrá romper robando el dispositivo de identidad asignado al usuario (y en biometría ya ni me meto :D ).

Ahora, basándonos en el principio de Kerckhoff, ten en cuenta que cualquiera sabrá como generas P, también sabrán como te comunicas con el servidor y que información recibirás del mismo. Sabrán que utilizas 3 coordenadas para la generación de P inicial, cada una de 5 dígitos (de 10.000 a 99.999 -> 89.999 valores posibles). Hallar esas tres coordenadas es complicado, se basa en un problema combinatorial con 7.28951401\cdot10^{14} posibilidades (V(89.999,3)).

El atacante comienza a desesperar por la complejidad de adivinar el trío de coordenadas, entonces empieza a estudiar con detenimiento la generación de P final suponiendo la P inicial (concatenación de las tres coordenadas). Si el atacante da con una breaktrough sobre la derivación de la P final a través de la inicial, entonces se habrá ahorrado adivinar el trío de coordenadas. El mismo sabe que P final cuenta con 30 dígitos, a simple vista, en el peor de los casos y siendo brutos, son 10^{30} posibilidades (muy muy brutos..). Sin embargo, día tras día, empieza a ser imas ingenioso, y se da cuenta de lo siguiente:

El quiere adivinar P_{final} = 429596212621582171952785642712 pero la desconoce. Sabe que cogiendo el primer dígito, tachándolo y contando el número de cifras hacia delante haya el siguiente número para seguir generando P_{final} pero como la inicial la desconoce, sigue sin sacar nada en claro. Entonces reconstruye P_{final}:

Supone que P_{1} = 42 y supone que el 4 es la última cifra de la primera coordenada y el 2 la primera cifra de la segunda coordenada. Por lo tanto supone que se ha contado 7 veces y ya tiene la primera cifra de la primera coordenada. A3 = 7xxx4. Ya sólo le falta calcular 3 dígitos de A3.

Como ves, esto último es un ataque más ingenioso, y es lo único que se me ocurre para atacar tu sistema, algo basado en la suposición y análisis por conteo. Puede que con tiempo y semanas, pueda ser capaz de obtener toda la matriz de coordenadas (tarjeta) haciendo pruebas con el servidor a ver si la P_{final} es la correcta, y sin robar nada al usuario.

Lo mejor es usar una tarjeta de coordenadas electrónica con renovación semanal/mensual dependendiendo del grado de seguridad, al estilo de los bancos. Sólo pides tres coordenadas al usuario y ya, no hace falta realizar más operaciones, y así te ciñes sólo a que el atacante tenga que adivinar 7.28951401\cdot10^{14} posibilidades (V(89.999,3)). Recalco, los bancos hacen esto y me parece, trivial, sencillo de implementar y estupendo, por que si recuerdas, ante un robo de credenciales, da igual que uses un sistema complejísimo y robusto o uno más simple pero robusto al mismo tiempo.

Dale un par de vueltas a mi respuesta y me comentas ;) Al final eres libre de usar el sistema que quieras, pero antes de implementar, sigue comentando tus ideas.

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 23 Noviembre 2016, 03:18 am
Muy buenas noches kub0x

Desconocía lo de Kerckhoff pero algunos puntos si que los sabia por otras lecturas ( como que mejor que sea conocido y fuerte por su propia fortaleza que por el ocultismo incluso que no sea muy complicado pero no se me ocurría otra cosa )


Por mi parte me gustaría uno con un simple click ni contraseñas ni nada, estilo captcha este "No soy un robot" pero estoy consciente que no es posible.


Llevo solo unos meses tocando un poquito mas de cerca el tema de la seguridad y al principio creí que con https se resuelve la cosa. Pronto me di cuenta que resuelve solo el transporte entonces he empezado ( cuando me ha quedado tiempo ) en alguna manera en cifrar los datos ... luego surgió la pregunta: ¿Y la clave donde lo guardo? ... y de allí llegue a CryptoJS para hacerlo desde el cliente ... el resto lo conoces.

Citar
imagina que al usuario se le roba su private-key pero esta esta cifrada por AES-256-CBC, no me quedaría otra que ver en que equipos posiblemente esté almacenada, pero quizá no lo esté... Con esto quiero decir que cuanta menos información se guarde mejor.

De acuerdo contigo pero llegamos al kelogger + los demás y estará cifrada por AES-256-CBC con una passphrase que tiene que introducir en la maldita casilla :D

Citar
Lo mejor es usar una tarjeta de coordenadas electrónica

No entiendo que quieres decir con electrónica. ¿Hay alguna con chip o algo así?

He mirado en google y lo que vi es (en la cajarural) "Tarjeta de firma electrónica"  o sea la llaman electrónica pero es la misma de las coordenadas nada de electrónico.  Además no voy a tener los medios al principio para permitirme esto.


Como te dije al principio sabía que no tiene que ser complicado y la manera en que la he pensado yo no solo que no es trivial ... Es un verdadero coñazo !!!... Imagínate medio planeta ( que intento conquistar  :D ) con sus bolígrafos, contando dígitos en sus tarjetitas ... y maldiciéndome a mi :D )))))

Claro que me gustaría algo más sencillo pero por ahora no se qué.

A no ser que no he entendido yo bien: O sea sin el rollo del conteo en el cual he pensado, ¿quieres decirme que es bastante robusto así pedir directamente 3 coordenadas ( y cambiar la tarjeta cada cierto tiempo )?

¿O quedarme  solo con la parte (de la idea que tenia) de la coordenada secreta + un pequeño conteo ( :D sin boligrafo) y escoger la coordenada que coincide con el conteo + dos vecinas?



Muchísimas gracias por tu ayuda kub0x

P.D.

Citar
En tu caso sucedería lo mismo, da igual cuantas veces cambies el sistema que si se le roba la tarjeta adios. Vale, el atacante no sabría el valor privado (a no ser que entre al server), pero teniendo la tarjeta del usuario, no tardaría mucho en adivinar el valor privado antes de que el usuario reporte el robo o se de cuenta de la intrusión

El valor privado no se guardaría en el servidor ... se envía al usuario al inscribirse (para que lo memorice) y no se guarda nada sobre el ni hash ni nada solo se guarda la diferencia entre el valor privado (D4) y el valor usado (A3) en el ejemplo seria la cifra 5 y a los 3 intentos si que el cliente sabrá porque se bloquea.

La tarjeta entera si tiene que guardarse con los otros datos del cliente a cifrar pero cifrados AES-CBC con la passphrase P.

A no ser que quieres decir que al saber esta distancia 5 ... intentara todas las posibilidades. Entonces se podrá mejorar hacer el cliente Que recuerde también esta diferencia (seria como su OTP).
O mejor que se renuncia al lio de guardar una secreta, luego recibir el intervalo y luego el conteo.
Darse cada vez que recuerde una como privada como su OTP


Lo que me gustaba mas con la P de 30 dígitos era que al menos para la fuerza bruta parecía mas fuerte (en teoria)

Pero si lo pienso bien ... con una normal (o sea 3 coordenadas 15 caracteres) pero con mayúsculas + minúsculas + dígitos tampoco no se queda demasiado lejos (en teoría fuerza bruta)

Ademas si le añado esto de que memorice siempre una privada como OTP, ni siquiera le digo que coordenadas tiene que ingresar que ya sabe una, mas dos vecinas

Hmm y aqui entra el keylogger o troyano   >:D  ;D cuando le voy a dar la siguiente OTP


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 23 Noviembre 2016, 04:48 am
El valor privado no se guardaría en el servidor ... se envía al usuario al inscribirse (para que lo memorice) y no se guarda nada sobre el ni hash ni nada solo se guarda la diferencia entre el valor privado (D4) y el valor usado (A3) en el ejemplo seria la cifra 5 y a los 3 intentos si que el cliente sabrá porque se bloquea.

La tarjeta entera si tiene que guardarse con los otros datos del cliente a cifrar pero cifrados AES-CBC con la passphrase P.

A no ser que quieres decir que al saber esta distancia 5 ... intentara todas las posibilidades. Entonces se podrá mejorar hacer el cliente Que recuerde también esta diferencia (seria como su OTP).


Vale entonces el servidor al generar la tarjeta por primera vez escoge D4 y un desplazamiento (5) para calcular A3 y sus vecinas, de esta forma calcula P. Pero si el servidor cifra la tarjeta con P, y sólo guarda el desplazamiento (5), ¿entonces en el siguiente login/autenticación como calcula el servidor P para descifrar el contenido de la tarjeta?. Me explico, la tarjeta estaría cifrada por P, y con el 5 no haría nada, le sería imposible calcular P.

La tarjeta sería mejor cifrarla con un user+pass+salt+iteracciones usando PKDF, así sí que podrías descifrar la tarjeta en cada sesión. Ahora con la tarjeta descifrada, lo óptimo sería cambiar P en cada sesión, por lo tanto el servidor debería conocer el valor privado para calcular un nuevo desplazamiento y hallar las nuevas coordenadas vecinas. Al cliente le enviaría sólo el desplazamiento y así calculan el nuevo P. Ahora el usuario cifra un mensaje aleatorio simetricamente con P (usando PKDF + AES-256 + HMAC) y el server comprueba la integridad del mensaje con P.

No sé, quizá me haya perdido algo :P

Con tarjetas electrónicas, me refiero a que envíes las coordenadas de la matriz/tarjeta por SMS o e-mail, siendo esta ultima mejor, así el usuario lo imprime y no tienes que entregarlas al estilo banco. Pides tres coordenadas en cada sesión y comparas en el lado del servidor que las coordenadas sean correctas. Es sencillo, práctico y seguro a la vez.

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 23 Noviembre 2016, 05:04 am
Citar
La tarjeta sería mejor cifrarla con un user+pass+salt+iteracciones usando PKDF + AES-256 + HMAC

Correcto.(solo que la tarjeta lo guardo junto con los otros datos a cifrar no separado)

Lo que si no creo que has entendido es que al cliente se le manda dicho intervalo -> el cliente regerera la P  y se lo manda asi como esta (por https TLS) al servidor o sea la P del cliente es la passphrase ..  usado para generar el key de  AES  con PKDF  para cifrar los datos en el servidor incluso la tarjeta

Al recibir la P correcta el servidor descifra , tiene la tarjeta , genera otros credenciales (otra P) otro key AES y cifra de nuevo con estas nuevas guardando otro intervalo (el nuevo) y destruye la llave y la P.

Al siguiente login el usuario solo recibe el intervalo nuevo ... regenera la P la manda al servidor y este puede usarla de nuevo como passphrase para regenerar la key ... esto si tiene que guardar tambien las iteraciones ... IV +salt ya los tiene

En el mensaje anterior he añadido algo al final ... justo cuando tu creo que me respondías ... que opinas ?



Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 23 Noviembre 2016, 05:41 am
Lo que si no creo que has entendido es que al cliente se le manda dicho intervalo -> el cliente regerera la P  y se lo manda asi como esta (por https TLS) al servidor o sea la P del cliente es la passphrase .. el pass que pusiste tu en la cita de arriba usado para AES  para cifrar los datos en el servidor

Era la otra forma que se me había ocurrido. No la he puesto en mi respuesta anterior ya que pensé: no creo que haga que el cliente mandé la passphrase al server. No lo veo conveniente por un motivo, en estos esquemas, lo suyo es que ambos generen P sin tener que compartirla, al igual que Shamir's secret sharing. Esto se debe a que si alguien monitoriza los key-exchanges y rompen RSA/ECC/DH podrán computar la clave AES y ver el passphrase, en cambio si ambos extremos generan P, el atacante debe conocer los valores privados. Aun así, lo dejo como "valido" (entre comillas :D ).

Ahora que el server es capaz de descifrar la tarjeta en cada sesión ya que el cliente le manda P, ¿cómo calcula el server la nueva P si sólo tiene el desplazamiento y no tiene el valor privado del cliente? Creo que cliente y server no podrán calcular la misma P en este caso, ya que si el server no sabe D4, no podrán establecer la misma passphrase. Para solucionar esto, el server al calcular la nueva P, elige una nueva privada, un nuevo desplazamiento y se los envía al cliente, de esta forma si podrían computar la misma P.

Pero si lo pienso bien ... con una normal (o sea 3 coordenadas 15 caracteres) pero con mayúsculas + minúsculas + dígitos tampoco no se queda demasiado lejos (en teoría fuerza bruta)

Ademas si le añado esto de que memorice siempre una privada como OTP, ni siquiera le digo que coordenadas tiene que ingresar que ya sabe una, mas dos vecinas

Hmm y aqui entra el keylogger o troyano   >:D  ;D cuando le voy a dar la siguiente OTP


Si añades caracteres alfanuméricos, el espacio de valores se incrementa y la complejidad de rotura también, pero bueno, con los 5 dígitos numéricos es suficiente.

Con lo de la privada y OTP, en OTP ambos extremos tienen que saber la clave. La nueva OTP, supongo que la entregas cuando el server computa la nueva P, como ya he dicho arriba, el server computa la nueva privada + desplazamiento y envía esa info al cliente, así ambos tienen la nueva P. Hombre, ya estás enviando la passphrase por el canal, no veo ningún incoveniente en que envíes dicha información también. Pero ojo, bajo el punto de vista puro de la crypto, esto no está bien  :-\ Se puede hacer, pero confiar en TLS y PKI es decir mucho :D

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 23 Noviembre 2016, 06:10 am
Citar
el server no sabe D4, no podrán establecer la misma passphrase

Tienes razon ... me he olvidado el maldito D4 .... intervalo hacia que hacia yo  ??? ;D

Citar
No la he puesto en mi respuesta anterior ya que pensé: no creo que haga que el cliente mandé la passphrase al server. No lo veo conveniente por un motivo, en estos esquemas, lo suyo es que ambos generen P sin tener que compartirla, al igual que Shamir's secret sharing


Supongo que tu tienes toda la razon ... al saber sobre el tema pero mi logica, no me deja entender por ahora en donde seria esto un problema ya que de este modo la P no existe en ningun lado .... solo cuando el cliente la envia ... en algunos milisegundos (segundos) queda inutilizable ya que una vez utilizada esta P ... en el servidor se genera otra , se cifra otra vez con otra P nueva, y despues se destruye . Por mucho que alguien ha capturado la P que mando el cliente ... ya no sirve ... ya hay otra .. empleada y destruida tambien.

Ya lo he pillado ... como la P son las coordenadas .... en 5 - 10 intentos tendra toda la tarjeta ... Solo le falta el D4 ... a por el servidor !!!    (o con un poco mas de paciencia ) ... lo adivinara pronto   :-(

.... A dormir ... en España son las seis y media de la mañana  ... y a soñar .... D4 y demas  :silbar:  ;D ... Gracias kub0x

¿Cual seria entonces tu consejo?

Lo leere luego ... Un saludo


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 23 Noviembre 2016, 07:08 am
en algunos milisegundos (segundos) queda inutilizable ya que una vez utilizada esta P ... en el servidor se genera otra , se cifra otra vez con otra P nueva, y despues se destruye . Por mucho que alguien ha capturado la P que mando el cliente ... ya no sirve ... ya hay otra .. empleada y destruida tambien.

Así es, en caso que se observe la primera P, el servidor descifrará la tarjeta con esa P, computará una nueva (segunda P) y destruirá la primera. Si alguién fue capaz de observar esa P o hacerse con ella de alguna forma, no valdría pa nada.

Pero no te me líes, el primer consejo que siempre se da a los iniciados en la crypto es, "Never implement your own crypto", con esto no quiero decir que jugetees con la crypto, pero en entornos profesionales es mejor implementar algo que sea considerado seguro por los expertos,

Yo te propondría lo siguiente:

- Servidor genera la tarjeta de coordenadas, se la entrega al usuario y la cifra con AES-256 usando la contraseña obtenida por PKDF -> user+pass+salt+iteracción. La pass es introducida en cada login por lo que descifrarla es posible una vez iniciada la sesión. Si consiguen acceso a tu server, no sabrán más que el hash+salt de la password, pero no sabrán la password que hay detrás del hash, por lo tanto no podrán obtener la tarjeta de coordenadas. Aun así si compremeten tu seguridad, lo ideal es avisar a todos los usuarios por mail y obligarles a cambiar sus credenciales, pero el atacante no podrá saber ni las passwords ni las tarjetas de cada usuario.
- En cada sesión, una vez hecho el login, descifras la tarjeta del usuario con PKDF, escoges 3 coordenadas al azar y le pides al usuario que te envíe su contenido (ej: Dime A3,D2,B1). El servidor compara si el contenido de esas coordenadas son las pedidas, si es así, ya lo has identificado correctamente.
- Como mejora, paranoia mode ON, después del login, el usuario y server podrían generar una nueva clave simétrica (PKDF -> user+pass+salt+it). Ahora el server al hacer el challenge de las 3 coordenadas, cifraría el challenge con esa clave y el usuario respondería cifrando el contenido de esas 3 coordenadas con esa clave simétrica. No sería necesario ya que TLS (HTTPS) ya cifra por defecto al establecer la comunicación, pero bueno, es una capa de seguridad más.

Otro esquema más y el que más me gusta desde el punto matemático, el más empleado en el real world:

-El usuario al registrarse en el servicio, genera en su equipo un par de claves RSA 2048-bit, envía su clave pública al server y guarda la privada firmada por AES-256 en su equipo. La clave simétrica para cifrar la privada la elige a gusto, pero HA DE RECORDARLA (si la pierde tendrá que avisarte).
- Después del login, el usuario genera una clave simétrica AES y un mensaje aleatorio. El usuario computa el SHA-256 sobre el mensaje y lo firma con su privada, esto es una firma digital sobre el mensaje. Ahora el usuario cifra el mensaje aleatorio con la simétrica y cifra la clave simétrica con la pública del servidor y envía al servidor el mensaje aleatorio cifrado, la clave simétrica cifrada por la pública del server y la firma digital.
- El servidor recibe el mensaje aleatorio cifrado por AES, la clave simétrica AES cifrada con la pública del servidor (su pública) y la firma digital. El propio server coge la clave simétrica cifrada y la descifra con su privada, coge la firma digital y la descifra con la pública del usuario (recuerda que fue guardada en el registro), coge el mensaje aleatorio y lo descifra con la simétrica obtenida. Ahora que tiene el mensaje aleatorio en plaintext, computa el SHA-256 y lo compara con el descifrado de la firma digital. Si son iguales, el servidor sabe que el mensaje fue firmado por el usuario y sabe que sólo el propio servidor puede descifrar la clave simétrica. Esto nos da una autenticidad REAL (PGP trabaja así cuando se utiliza RSA+AES).

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 23 Noviembre 2016, 12:45 pm
Citar
Otro esquema más y el que más me gusta desde el punto matemático, el más empleado en el real world:

-El usuario al registrarse en el servicio, genera en su equipo un par de claves RSA 2048-bit, envía su clave pública al server y guarda la privada firmada por AES-256 en su equipo. La clave simétrica para cifrar la privada la elige a gusto, pero HA DE RECORDARLA (si la pierde tendrá que avisarte)


Ok entendido.

Lo que desconozco por ahora sobre este sistema, es como implementarlo en el lado cliente.

Mirando un poco por la web di con esta libreria javascript.

https://github.com/wwwtyro/cryptico

Si tienes un minuto para mirar el Overview de la misma a mi me parece que encajaría con lo que propones tu.

Lo que no se, son los pasos que habría tenido que hacer el cliente para cumplir lo que me dijiste arriba

Te pongo aquí dichos pasos tal como lo pienso yo (para ver si he entendido bien) :

- emplear esta librería, u otra parecida a esta en el lado cliente (vi otras discusiones sobre la fiabilidad de las mismas en http://crypto.stackexchange.com/questions/10200/is-javascript-rsa-signing-safe pero parece que cumple ... tu que opinas ?) y generar el par de claves RSA

- sacarle una casilla en donde tiene que ingresar su passphrase para cifrar su llave privada con AES-256 (ya tengo esta otra librería probada )

Aquí tengo una duda Se necesitan 2 Passphrases una para RSA y otra para AES
¿Se utiliza la misma (la que el usuario tiene que memorizar)?

- y al pulsar enviar que mande al servidor su publica (eventualmente en el mismo tiempo con sus datos de inscripción)

- Luego sacarle en una caja de texto la clave suya privada y cifrada con RSA, codificada en base64 para ser compatible ASCII
- el cliente copia la misma y se la guarde como texto en su maquina  (mejor en una usb o tarjeta ssd etc) (Modo paranoia ON -> Esteganografia para privada cifrada con RSA :D )


- Después del login le pongo una caja de texto en donde tiene que pegar su clave privada (ya que con javascript no se pueden abrir ficheros ... aunque vi algo en el mismo HTML5 que tiene una API creo... lo mirare)

- Otra casilla en donde tiene que ingresar su passphrase  y ... "Lo he dejado a los matemáticos" :D

Si es así el resto lo entendí todo.




Me gustaría, si puedes, confirmarme (o no) si los pasos que hago en el lado cliente son correctos o si tu habría pensado en otra cosa.

Un saludo.


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 24 Noviembre 2016, 02:21 am
He revisado el overview de la librería, así como aspectos técnicos y código fuente de funciones cruciales como generación de la clave RSA, AES e IV.

La passphrase vista aquí:

Código
  1. // The passphrase used to repeatably generate this RSA key.
  2. var PassPhrase = "The Moon is a Harsh Mistress.";
  3.  
  4. // The length of the RSA key, in bits.
  5. var Bits = 1024;
  6.  
  7. var MattsRSAkey = cryptico.generateRSAKey(PassPhrase, Bits);

Sirve para generar entropía tomando el SHA-256 de la passphrase, de esta forma se generará la clave RSA dependiendo de un hash único. Haz un PBKDF user+pass+salt+it y pásaselo a generateRsaKey como la passphrase. Si dos passphrase son iguales, también lo serán las private key.

Esto es importante también:

Citar
Encryption

A 32-byte AES key is generated with Tom Wu's random number generator. The plaintext message is converted to a byte string and padded with zeros to 16 bytes round. An initialization vector is created with Tom Wu's random number generator. The AES key is expanded and the plaintext message is encrypted with the Cipher-block chaining mode using the jsaes library. The AES key is encrypted with the recipient's public key using Tom Wu's RSA encryption library.

Cada vez que se quiera cifrar un mensaje, se genera una clave AES aleatoria (no confundir con la AES de la privada del usuario). Aquí no necesitas establecer ninguna passphrase para AES (menos trabajo para tí), la propia librería subyacente generará la entropía necesaría para que las claves sean distintas en cada generación. Es importante, ya que si usaramos una passphrase inicial y alguien la adivina, sería trivial adivinar la secuencia de claves AES generada por el PRNG.

Citar
Aquí tengo una duda Se necesitan 2 Passphrases una para RSA y otra para AES
¿Se utiliza la misma (la que el usuario tiene que memorizar)?

Genera la passphrase para RSA como he mencionado arriba, úsala para generar el par de claves RSA, ahora obliga al usuario a introducir otra passphrase (textbox?) que con PBKDF genere una clave AES para cifrar la privada RSA. Una vez generado el par, no vuelvas a usar passphrases (JAMÁS, como ya he dicho), ya que estas dos passphrases SÓLO se usan para generar el par público/privado + AES para la private RSA. El resto de claves AES serán aleatorias para cifrar mensajes. Espero se entienda porque esto es lo más importante.

La librería lleva 4 años sin actualizarse. Pero no nos alarmemos, no es más que una interface en high level de las liberías de http://www-cs-students.stanford.edu/~tjw/jsbn/ las cuales parecen seguras ya que utilizan el padding PKCS#1 y CBC con padding también así que perfecto. El exponente es 3 en vez de 65537, verás mucho novato diciendo que son vulnerables, pero realmente no es así, es cuestión del padding pero al ser PKCS no hay problema, de hecho usando 3 es más rápida.

Citar
- y al pulsar enviar que mande al servidor su publica (eventualmente en el mismo tiempo con sus datos de inscripción)

- Luego sacarle en una caja de texto la clave suya privada y cifrada con RSA, codificada en base64 para ser compatible ASCII
- el cliente copia la misma y se la guarde como texto en su maquina  (mejor en una usb o tarjeta ssd etc) (Modo paranoia ON -> Esteganografia para privada cifrada con RSA :D )


- Después del login le pongo una caja de texto en donde tiene que pegar su clave privada (ya que con javascript no se pueden abrir ficheros ... aunque vi algo en el mismo HTML5 que tiene una API creo... lo mirare)

- Otra casilla en donde tiene que ingresar su passphrase  y ... "Lo he dejado a los matemáticos" :D

-Correcto, se envía la pública del usuario + sus datos personales.
-En el textbox sacas la clave privada cifrada con AES (no por RSA  :P), en b64 ASCII creo que debería ser así el formato estándar, correcto.
-Exacto, el cliente copia la clave privada cifrada con AES en una memoria USB al ser posible o en su PC alternativamente.
-Sí, después del login tendrá que poner en un textbox la privada cifrada con AES y otro textbox para coger la passphrase que se utilizó para generar la clave AES que cifra la privada. De esta forma descifrar la private RSA y ya podrás intercambiar mensajes que cumplan las firmas digitales para probar la autenticación.

Siguiendo estos pasos tendrás un mecanismo de autenticación muy robusto, ya que si comparamos el robar la tarjeta de coordenadas del usuario con robarle la private key cifrada con AES, pues obviamente con la tarjeta suplantamos al usuario, pero con la private cifrada podemos estár 100 veces la vida del universo intentando ataques que no podríamos hacer nada (el atacante tendría que adivinar la passphrase AES (díficil si obligas al usuario a escoger una clave 10+ carácteres alfanuméricos).

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 24 Noviembre 2016, 14:45 pm
Gracias kubox,

En principio me ha quedado todo claro.


Citar
Haz un PBKDF user+pass+salt+it y pásaselo a generateRsaKey como la passphrase. Si dos passphrase son iguales, también lo serán las private key.

¿Aportaria alguna mejora si hago asi?

Como tengo otra libreria (CryptoJS) para AES (cada una con sus pro y contras ) intentare aprovechar lo mejor de cada una por ejemplo:

CryptoJS tiene SHA3-512 PBDKF2 y Pkcs7 para padding pero no tiene PRNG
En cambio cryptico tiene PRNG pero hashes mas flojos pbdkf1 y padding con ceros

Entonces usare PRNG de la libreria cryptico para generar IV y salt
y generare la key usando la libreria CryptoJS

Código
  1. var key = CryptoJS.PBKDF2(passphrase, salt, { hasher: CryptoJS.algo.SHA3-512, keySize: 4, iterations: it });
  2. //keySize: 4 es para 32bytes
  3.  


hmm el padding se queda con ceros (pero voy a mirar si puedo emplear CryptoJS para AES en vez de AES que tiene "cryptico"

Apropósito: Desde algunos meses que hemos hablado la primera vez me he quedado con una duda:
El numero de iteraciones ... hay que guardarlo en algún lugar ?  no se si te acuerdas que me dijiste que algunos emplea un rango de tiempo 9-10 milisegundos ...

Entonces cuando uno va a descifrar con AES ¿como saber cuantas iteraciones poner?


Citar
la clave privada cifrada con AES (no por RSA  :P)
:D Ha sido solo una confusión de términos (al no ser muy acostumbrado con ellos)  ... en la cabeza la tenia correcto AES y no RSA.


Citar
- Después del login, el usuario genera una clave simétrica AES y un mensaje aleatorio. El usuario computa el SHA-256 sobre el mensaje y lo firma con su privada, esto es una firma digital sobre el mensaje. Ahora el usuario cifra el mensaje aleatorio con la simétrica y cifra la clave simétrica con la pública del servidor y envía al servidor el mensaje aleatorio cifrado, la clave simétrica cifrada por la pública del server y la firma digital.
- El servidor recibe el mensaje aleatorio cifrado por AES, la clave simétrica AES cifrada con la pública del servidor (su pública) y la firma digital. El propio server coge la clave simétrica cifrada y la descifra con su privada, coge la firma digital y la descifra con la pública del usuario (recuerda que fue guardada en el registro), coge el mensaje aleatorio y lo descifra con la simétrica obtenida. Ahora que tiene el mensaje aleatorio en plaintext, computa el SHA-256 y lo compara con el descifrado de la firma digital. Si son iguales, el servidor sabe que el mensaje fue firmado por el usuario y sabe que sólo el propio servidor puede descifrar la clave simétrica. Esto nos da una autenticidad REAL (PGP trabaja así cuando se utiliza RSA+AES).

El proceso en si, después del login lo he entendido, pero como nunca he trabajado con RSA me queda una duda.
 (casi dos con lo de firmar "y lo firma con su privada") ... supongo que "firmar" quiere decir también "cifrar" con su privada (en este caso) ...
entonces si es así me queda solo una duda:

En el proceso de cifrar con las claves publicas (mia y la del usuario) y privada del usuario
¿se utiliza AES para cifrar y se emplean dichas claves como passphrase para crear una clave AES ? Si seria asi , no hace falta que me expliques como se hace porque esto ya lo se hacer. (PBKDF+passphrase+SHA+IV+salt+it)
¿O es un cifrado que se hace de alguna forma (diferente de AES) con el mismo RSA?
(cosa que por ahora desconozco ... intentare ahora averiguarlo )


Ok creo  lo he averiguado.
para el lado cliente en la misma libreria js pone un ejemplo:
Citar
cryptico.encrypt(PlainText, MattsPublicKeyString);
y en el servidor con openssl.

Saludos


P.D ... Perdona si me he puesto pesado con tantas preguntas pero prefiero estar seguro que he entendido todo

 




 







Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 26 Noviembre 2016, 08:08 am
Citar
CryptoJS tiene SHA3-512 PBDKF2 y Pkcs7 para padding pero no tiene PRNG
En cambio cryptico tiene PRNG pero hashes mas flojos pbdkf1 y padding con ceros

Entonces usare PRNG de la libreria cryptico para generar IV y salt
y generare la key usando la libreria CryptoJS

Ojo, CryptoJS y Cryptico ambos implementan padding PKCS7# sólo que CryptoJS en el padding introduce N bytes cuyo valor es N y Cryptico Zero padding. Me quedo con el de CryptoJS.
Sí, lo mejor sería generar una clave AES llamando a la funcion:

Código
  1. my.generateAESKey = function()
  2.    {
  3.        var key = new Array(32);
  4.        var r = new SecureRandom();
  5.        r.nextBytes(key);
  6.        return key;
  7. }

La cual devuelve la clave AES-256 aleatoria usando el PRNG de Cryptico, el cual es seguro ya que tiene la suficiente entropía para no tener una tendencia (bias). Ahora usa esa clave aleatoria para cifrar con AES-CBC en CryptoJS (por el tema del padding).

Entonces, como hemos dicho. Al registrarse el usuario se genera la private key RSA mediante PKBDF2 -> user+pass+salt+it y oblígale a introducir un passphrase que generará la clave AES PKBDF2 -> passphrase+salt+it. Cifra la privada mediante AES, haz que guarde la privada cifrada en algún sitio y deshazte de la clave AES.

Citar
Ok creo  lo he averiguado.
para el lado cliente en la misma libreria js pone un ejemplo:

cryptico.encrypt(PlainText, MattsPublicKeyString);

y en el servidor con openssl.

Ahí sólo estás cifrando un mensaje con la pública. No veo que estés generando una clave AES aleatoria, ni un mensaje, ni una firma digital ni nada de lo que dije anteriormente :D

Arriba he mostrado como generar una key AES-256 aleatoria. El mensaje a cifrar puede ser el mismo ya que el IV hace que en cada cifrado el ciphertext sea distinto, lo mejor aun así es generar un mensaje aleatorio con el PRNG. Vale ya sabes como generar una clave AES y mensaje aleatorios.

Ahora tienes que hacer la firma digital sobre el mensaje, cryptico utiliza esta función para ello:

Código
  1. function _rsasign_signStringWithSHA256(s)
  2. {
  3.    var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), 'sha256');
  4.    var biPaddedMessage = parseBigInt(hPM, 16);
  5.    var biSign = this.doPrivate(biPaddedMessage);
  6.    var hexSign = biSign.toString(16);
  7.    return hexSign;
  8. }

La firma digital también lleva padding y acuérdate que internamente computa el SHA-256 del mensaje, le añade padding y lo firma con la privada (cifrar con la privada está mal dicho realmente, no gusta en el argot de la crypto).

Sólo falta que cifres la clave AES-256 aleatoria con la pública del servidor, como has puesto en el ejemplo. Y ya tienes: clave AES aleatoria cifrada por pública de servidor, mensaje aleatorio cifrado por clave AES aleatoria y firma digital sobre mensaje aleatorio. Manda esa info al server y el server se ocupara de:

Descifrar la clave AES con su privada (la del server). Descifrar el mensaje cifrado por AES y llamar a la función:

Código
  1. function _rsasign_verifyHexSignatureForMessage(hSig, sMsg)
  2. {
  3.    var biSig = parseBigInt(hSig, 16);
  4.    var result = _rsasign_verifySignatureWithArgs(sMsg, biSig, this.n.toString(16), this.e.toString(16));
  5.    return result;
  6. }

La cual coge el mensaje descifrado por AES y la firma digital y verifica si en efecto el mensaje no ha sido alterado. De esta forma has autenticado al 100% al otro extremo.

NOTA: Te pongo el código de las funciones para que veas un poquito como se comportan por dentro, aunque hagan llamdas internas, es más facil dartelo así que sólo el nombre de la función a la que tienes que llamar. Esto hace que te familiarices un poco más con la librería.

Entiendo que es un tema extenso y más cuando primero tienes que entender lo que estás haciendo antes de implementar nada, ya que pondrías en riesgo toda la infraestructura si no encajas bien las piezas. Si no entiendes algo, pues aquí estoy para lo que necesites.

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 26 Noviembre 2016, 15:48 pm
Citar
Si no entiendes algo, pues aquí estoy para lo que necesites.

No sabes cuanto te lo agradezco kub0x !

Al intentar aprender todo como autodidacta (cosas de la vida + tonterias de la juventud) pues aprendo trocitos de cosas quedándome siempre partes que estoy saltando (por no saber de su existencia)

Ojala el proyecto que tengo en la cabeza ira bien, entonces no voy a olvidar tu ayuda te lo aseguro !


Citar
Citar
Ok creo  lo he averiguado.
para el lado cliente en la misma libreria js pone un ejemplo:

cryptico.encrypt(PlainText, MattsPublicKeyString);

y en el servidor con openssl.

Ahí sólo estás cifrando un mensaje con la pública. No veo que estés generando una clave AES aleatoria, ni un mensaje, ni una firma digital ni nada de lo que dije anteriormente :D


Puse solo como un resumen ... (el proceso en si, lo he entendido ... por esto puse lo de usar lo mejor de las dos librerías ... solo estaba un poco confundido con lo del padding )


Sin embargo en lo de la firma , cuando escribi el mensaje puse una pregunta (no se si lo habrás leído) donde te preguntaba si esto de la firma es otro proceso o bien es simplemente un cifrado con AES ... pero luego ... he deducido (MAL) que si, que solo es otro cifrado AES (al que tu llamaste firma) así que borre dicha pregunta.

Ahora que me pusiste las funciones en js ... me puse a encontrar su equivalente en openssl y creo haber encontrado algo el "dgst" (aunque los ejemplos que encontré eran para firmar-verificar un fichero de texto ) de todos modos me doy cuenta que estoy cerca así que lo averiguare por mi mismo.


Ahora ya que se me ha quedado en la cabeza el proceso entero (al menos este cual tratamos aquí en este hilo),
me falta todavía practicarlo un poco cuando tendré tiempo (lo de AES ya he echo practicas queda RSA + esta firma )


O sea ahora de punto de vista matemático seria digamos aceptable como robustez

Los puntos débiles que le veo por ahora serian: la intrusión en algunos (o ambos) de los lados cliente - servidor y/o el phishing + eventualmente la criptoanalisis

Por otro lado, en mi codigo php tengo ya hecha (trabajando en local) la verificación y saneamiento de todos los datos de entrada + PDO + procedimientos almacenados para la interacción con la base de datos
Para el servidor también: redirecionamiento https + HSTS + Hardening & Security cabeceras (XSS, CSRF, secure httponly cookies etc)

Volviendo al tema:
Ahora ya con lo que se sobre AES si RSA intentare reforzar un poco la lógica del login (ya no empleare métodos de la edad de piedra para que el usuario tenga que contar hieroglifos en una tabla sumeria :D )

A ver que te parece.

Asumiendo que el usuario pilla algun keylogger virus troyano etc, o peor un acceso a su maquina o se le hace un phishing. Entonces esto comprometería todo.

Por esto voy a dividir el acceso a los usuarios en dos partes:
-una para poder trabajar solo con usuario + contraseña, en donde si alguien le roba su contraseña o la sesión que no le afecte
-y otra para los datos sensibles donde tendrá que utilizar su clave privada (como ya hemos hablado)


En el proceso de inscripción (aparte de lo que hemos hablado) voy a añadir también una OTP que lo va a recibir por SMS (de todos modos voy a tener que comprobar su teléfono.
 Lo que no me puedo permitirme al principio, es usar SMS como segundo factor siempre en cada login ... no todos somos ricos :D )

con esta OTP puedo cifrar su publica al enviarla al servidor y luego que me envía los otros datos ya cifrados con su privada + firma etc, como si seria el primer login.

Entonces esto sera un poco mas cómodo para el cliente ya que solo de vez en cuando tendra que emplear su clave privada ademas la esta exponiendo menos.

O sea la privada del cliente solo se empleara como autorización para los datos sensibles o si se logea de otra maquina (o ha borrado la cookie de su maquina)

-Dicha cookie no va a ser para guardar su sesión (siempre voy a pedir user+pass para login aunque tenga cookie)
 pero la empleare como si seria una OTP una vez usado generare otra (cifrada en el servidor + httponly + secure)

Así que si se le roba el pass o esta cookie otra vez SMS + su privada (como hemos hablado) Si alguien abusa de SMS hago que mande el a mi un SMS.

Entonces aunque se le ha robado incluso su privada + su passphrase queda el SMS como OTP.

Ademas al mandarle el SMS, lo voy a emplear también para cifrar la publica del cliente que tengo en el servidor.
Me mando esta clave que he empleado a mi mismo y la destruyo (asi cubro tambien la parte del servidor)

Ahora (desde mi punto de vista quedarían estas debilidades seguro son mas :D pero no me doy cuenta):

-Que el atacante haga todo el proceso ar revés
 
O sea primero hacerse con la publica del cliente que tengo en servidor y luego que robe al menos user+pass+privada+passphrase del usuario y usarlos para descifrar los datos del cliente.

¿Tendrás alguna idea al respecto para evitar esto? (claro que no entre! pero si entra ... creo que ya me dijiste ... si entra .... no sirve de nada el cifrado )

Y la segunda seria criptoanalisis en lo cual soy NULO !

Por esto mi pregunta es:
 ¿ayudaría que los passphrases del cliente para la generación del primer par RSA y la del AES (usada para cifrar su privada) serian algo complicadisimos y largos?

Algo así (mas complejos todavía pero no me deja el foro ponerlos aquí:
Citar
¥ö `ŠúZtq¯>à@I?¥øƒafF ÁƒpÂé‡ 臬qúy_Ðpà„Á?ð8‡7`ÆRÍØU±+XøŒàBb:9^ƒPCmêm“oU›í£è\õ':ë`µNžTêOfEùÁŸ =:/ðf£­e


Ya te preguntaras ¿Y como se supone que va memorar el usuario tal cosa?

He pensado en hacer que el usuario guarde su privada y su passphrase en unas fotos (esto si no juntas)

Por esto quiero usar para que escoja unas fotos que se puede recordar usando

Citar
FileReader(); //para abrir las fotos en el lado cliente
readAsBinaryString(); // para generar la passphrase


y emplear esta librería:  https://eligrey.com/demos/FileSaver.js/ (https://eligrey.com/demos/FileSaver.js/)

para que el cliente guarde de manera mas sencilla su privada y su passphrase (esto si AVISANDOLE QUE NO LAS GUARDE en la maquina por lo menos la foto de passphrase) ... de todos modos podre emplear el SMS que recibe para crear un algoritmo de regenarcion de passphrase en base a dicha foto

Todo esto en el lado cliente sin necesidad del servidor.

Apropósito servirá de algo, que antes de introducir su foto (usada como passphrase) le obligo que se desconecte de internet ?
Puedo chequear si tiene conexión y sugerirle que se desconecte antes de introducir su privada y su passphrase luego quitar la memoria (ssd o usb) y volver a conectarse para continuar el proceso  

Se que es muy paranoia pero de este modo solo seria complicado para mi hacerlo y no para el usuario emplearlo asi que puedo cumplir tambien con lo de Kerckhoff (menos lo de desconectarse de internet).


Bueno ojala funcione bien lo que intento hacer como negocio y si se gana algo emplear personas calificadas para estos propósitos creo que seria lo mejor pero hasta entonces tendré que sobrevivir

Te aseguro que no me olvidare de ti tampoco

Gracias por tu paciencia y tu extensa ayuda  ... me ha servido mucho

Ahora como he dicho practicar (cuando puedo) y te molestare de vez en cuando con alguna duda puntual y no escribirte mas novelas como esta

Un saludo y felicitaciones por lo que haces








Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 29 Noviembre 2016, 05:21 am
Buenas noches Matake,

me alegro de que vayas pillando los conceptos y sepas como juntarlos, aun así todavía veo alguna cosa que no te ha quedado del todo clara jeje intentaré ayudarte. Empecemos:

Citar
Sin embargo en lo de la firma , cuando escribi el mensaje puse una pregunta (no se si lo habrás leído) donde te preguntaba si esto de la firma es otro proceso o bien es simplemente un cifrado con AES ... pero luego ... he deducido (MAL) que si, que solo es otro cifrado AES (al que tu llamaste firma) así que borre dicha pregunta.

La firma no es otro cifrado con AES, una firma creo que la vés como MAC, pero esto es una firma DIGITAL :D . Una firma digital sirve para que el destinatario compruebe que el mensaje no fue modificado y proviene de la fuente original y no de un atacante. Se basa en probar que la firma digital fue creada por la clave privada del emisor.

Creo que lo he explicado dos veces por los anteriores post, pero centraré más atención esta vez en el proceso de firma digital. La función de firma digital también la puse arriba, te hare quote de ella:

Código
  1.    function _rsasign_signStringWithSHA256(s)
  2.    {
  3.        var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), 'sha256');
  4.        var biPaddedMessage = parseBigInt(hPM, 16);
  5.        var biSign = this.doPrivate(biPaddedMessage);
  6.        var hexSign = biSign.toString(16);
  7.        return hexSign;
  8.    }

¿Y cómo se computa una firma digital sobre un mensaje? Nosotros somos el emisor y queremos provar al destinatario que el mensaje que vamos a enviar no ha sido modificado y que realmente somos nosotros al 100% quien ha enviado ese mensaje. Entonces:

- Generamos un mensaje y computamos el SHA-256 del mismo.
- Añadimos un padding a dicho Hash (sino varios mensajes iguales tendrían la misma firma digital, sería un big fail).
- Ahora firmamos con la privada el hash y ya tenemos la firma digital sobre el mensaje.

Ahora el destinatario recibe el mensaje y la firma digital, el destinatario (servidor) posee la clave pública del usuario (recuerda que la entregó en el sign-up o registro).

- Computa el SHA-256 del mensaje.
- Descifra la firma digital con la pública del usuario.
- Compara el primer Hash y el del descifrado de la firma digital, si ambos hashes son iguales, entonces sabemos que el mensaje no fue modificado y que proviene del emisor (nosotros) ya que la clave pública está relacionada con la privada, y la privada del emisor firmó el mensaje.

Vale, ya está explicado con todo detalle el proceso de firma digital y en que se basa.

Citar
Los puntos débiles que le veo por ahora serian: la intrusión en algunos (o ambos) de los lados cliente - servidor y/o el phishing + eventualmente la criptoanalisis

Por otro lado, en mi codigo php tengo ya hecha (trabajando en local) la verificación y saneamiento de todos los datos de entrada + PDO + procedimientos almacenados para la interacción con la base de datos
Para el servidor también: redirecionamiento https + HSTS + Hardening & Security cabeceras (XSS, CSRF, secure httponly cookies etc)

La intrusión en el server no ayudaría en nada, ya que sólo obtendrían hashes salteados de las password, las públicas de los usuarios y su username. Los datos sensibles deberías cifrarlos con una simétrica que detallaré luego el como se genera. Si instalan keylogger al usuario no es tu problema, recuérdalo. Si capturan la private key del user, tendrían que romper AES o brute force a la passphrase. Así que no te preocupes.
Las medidas de protección del server me parecen ideales, HSTS para evitar SSL-Stripping, TLS over HTTPS con ECDHE_ECDSA_AES-256-GCM al poder ser, pregúntame luego si quieres el por que :D y un buen NIDS (Network Intrusion Detection System o Firewall), httponly para no capturar cookies por JS y todo sanitizado, si señor. Por el criptoanálisis, no te preocupes, es seguro (hasta que venga el PC cuántico) mientras implementes todo bien claro.

Por lo que veo te preocupa mucho que descifren los datos del usuario almacenados en tu servidor. Te voy a proponer lo siguiente. Teniendo en cuenta que tu eres más cuidadoso que cualquier usuario, vamos a proteger bien esa información, para que en caso de intrusión, no puedan ni descifrar los datos del usuario.

El usuario hace sign-up por primera vez:

- Genera un par de claves RSA en el lado del servidor. Esto ya contábamos con ello ¿por qué sino como cifra el usuario la simétrica AES sobre el mensaje aleatorio?. La privada RSA es única (un mismo par para todo) y cifrála con el passphrase que desees en AES-256.
- El usuario computa una firma digital sobre su info y cifra dicha info con una clave AES aleatoria. El user cifra la clave aleatoria AES con la pública del server y envía todo lo especificado aquí al server.
- El server descifra la clave AES con su privada (la del server obvio), descifra el mensaje con la clave AES y verifica la firma digital. Si todo va bien, re-cifra la info del usuario, cifra la clave AES con la pública del server y guarda la info cifrada por AES y la clave AES cifrada por la pública RSA.

Ahora si entrán a tu server, verán que la info de todos los usuarios está cifrada, y también verán que hay una clave AES cifrada por la pública de tu server. Entonces pensarán, bueno sólo necesito descifrar la info por la key AES, vale vamos a buscar la private key del server. Digamos que la encuentran, pero no verán más que la privada tuya cifrada por AES.

La autenticación la hacemos como te dije, generas mensaje y clave AES aleatoria. Computas firma digital con la privada del usuario sobre el mensaje aleatorio y cifras el mensaje con AES. Envías la info al server y el server descifra la AES con su privada (la del server), descifra el mensaje con la AES y computa la firma digital con la pública del cliente. Si la firma digital es satisfactoria entonces has autenticado al cliente al 100%.

Como ves es un esquema fuerte en el que si sólo observan mensajes necesitan un ordenador cuántico para atacar el protocolo. Si entran al servidor no podrán saber la info de los usuarios ya que necesitan la privada del servidor. Si comprometen al cliente, todo depende de su seguridad, si roban su privada y la passphrase que la protege entonces se podrán autenticar, para eso lo mejor es que hagas como GMAIL, guarda la IP o el PC mediante cookie y si cambia de PC o de rango de IP entonces avísalo y hasta que no confirme no le dejes entrar.

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 30 Noviembre 2016, 14:50 pm
Muy buenas ,

Citar
La firma no es otro cifrado con AES, una firma creo que la vés como MAC, pero esto es una firma DIGITAL

Gracias por los detalles que me diste esto me aclaro todo.
Caso cerrado lo de la firma :D




Citar
El usuario hace sign-up por primera vez:

- Genera un par de claves RSA en el lado del servidor. Esto ya contábamos con ello ¿por qué sino como cifra el usuario la simétrica AES sobre el mensaje aleatorio?. La privada RSA es única (un mismo par para todo) y cifrála con el passphrase que desees en AES-256.
- El usuario computa una firma digital sobre su info y cifra dicha info con una clave AES aleatoria. El user cifra la clave aleatoria AES con la pública del server y envía todo lo especificado aquí al server.
- El server descifra la clave AES con su privada (la del server obvio), descifra el mensaje con la clave AES y verifica la firma digital. Si todo va bien, re-cifra la info del usuario, cifra la clave AES con la privada del server y guarda la info cifrada por AES y la clave AES cifrada por la privada RSA.

Ahora si entrán a tu server, verán que la info de todos los usuarios está cifrada, y también verán que hay una clave AES cifrada por la privada de tu server. Entonces pensarán, bueno sólo necesito descifrar la info por la key AES, vale vamos a buscar la private key del server. Digamos que la encuentran, pero no verán más que la privada tuya cifrada por AES.

La autenticación la hacemos como te dije, generas mensaje y clave AES aleatoria. Computas firma digital con la privada del usuario sobre el mensaje aleatorio y cifras el mensaje con AES. Envías la info al server y el server descifra la AES con su privada (la del server), descifra el mensaje con la AES y computa la firma digital con la pública del cliente. Si la firma digital es satisfactoria entonces has autenticado al cliente al 100%.


Segun entiendo , en esta propuesta el usuario ya no genera sus claves RSA (como hemo hablado anteriormente).
Las genera el servidor y se los manda al usuario (¿es esto correcto?)

Aunque creo que he entendido luego el proceso de autenticacion, estoy un poco perdido en esto:

Citar
Ahora si entrán a tu server ... vamos a buscar la private key del server ... Digamos que la encuentran, pero no verán más que la privada tuya cifrada por AES.

Y dicha clave AES (la que utilizo para cifrar la privada mía) tendré que tenerla fuera del servidor ... sino no le veo lógica. ¿Es esto correcto?

Si es así ... entonces entiendo que la publica me basta para autenticación 100%,
pero en este caso (si no me equivoco) aunque este autentificado, el usuario no puede descifrar sus datos.

A no ser que no he entendido  bien el proceso

Tambien estoy un poco confundido cuando me dices de las privadas del servidor
¿Hablamos solo de la privada del user generada por servidor? o de dos privadas una del user y otra mia (ambas presentes en el servidor).

Un saludo


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: kub0x en 2 Diciembre 2016, 11:01 am
Buenas matake, por lo que veo tienes un lío en esto:

Citar
Y dicha clave AES (la que utilizo para cifrar la privada mía) tendré que tenerla fuera del servidor ... sino no le veo lógica. ¿Es esto correcto?

Si es así ... entonces entiendo que la publica me basta para autenticación 100%,
pero en este caso (si no me equivoco) aunque este autentificado, el usuario no puede descifrar sus datos.

A no ser que no he entendido  bien el proceso

Tambien estoy un poco confundido cuando me dices de las privadas del servidor
¿Hablamos solo de la privada del user generada por servidor? o de dos privadas una del user y otra mia (ambas presentes en el servidor).

Quizá me haya explicado mal en ese sentido, espero que ese post sirva para aclarar todas tus dudas sobre el proceso de generación de claves en el sign-up y sobre el proceso de autenticación.

Primero antes de todo, el usuario y el servidor tienen dos pares RSA distintos, ambos de 2048-bit. La clave privada del servidor estará cifrada por una clave AES que tu has generado (sólo tu conoces). Esa clave es conveniente que esté en otro lugar distinto al servidor, o que para tener acceso se necesite de privilegios root. El par RSA del usuario lo debe general el mismo, no el servidor. Si sólo existiera el par de claves en el lado del server, el usuario no podría computar firmas digitales, por lo tanto cualquiera ha podido enviar información al server y tu no sabrías como autenticar dicha información.

Para cifrar los datos del usuario, la primera vez que el usuario hace sign-up (registro), se genera un par de claves para ese usuario, le obligas a introducir una passphrase que derivarás en una AES y cifrarás su privada con ella (todo esto del lado del usuario repito). Ahora se genera una AES aleatoria de lado del usuario, se computa una firma digital con la privada del usuario sobre sus datos, se cifran los datos por esa AES aleatoria y se cifra la AES aleatoria con la pública del server.

El usuario envía AES aleatoria cifrada por pública del servidor, datos cifrados por AES aleatoria y firma digital sobre los datos.

El servidor recibe dichos datos, descifra la AES con la privada del servidor, descifra los datos del usuario con la AES descifrada y verifica la firma digital sobre esos datos descifrados con la pública del usuario. La pública del usuario has de enviarla de alguna forma antes de este proceso. Si la firma digital es correcta entonces sabes que los datos del usuario no han sido modificados y que el usuario hizo la firma digital con su privada y nadie más pudo, así que autenticado al 100%.

Ahora guardas en la DB del server los datos cifrados por esa AES y guardas la clave AES asociada a esos datos cifrada por tu pública (la del server). Así si entran al server no podrán leer los datos de cada usuario, porque la clave AES que los descifra está cifrada por tu pública (sólo se puede descifrar por la privada tuya), y como tu privada está protegida con una AES que sólo tu conoces, pues, game over para el attacker.

¿Pero como descifra esos datos el usuario? Bueno, ese trabajo lo haces tú. Coges la info cifrada del usuario, la clave cifrada AES asociada a esa info y descifras con tu privada la AES asociada a esos datos y posteriormente los datos. Ahora los datos están en plano y se los puedes presentar al usuario. Si el usuario los modifica puedes obligarle a repetir el mismo proceso de generar AES aleatoria, firma digital sobre los nuevos datos etc, para que cada vez que cambien los datos se le asocie una nueva AES.

Ahora sólo queda el proceso de autenticación, que es lo mismo pero con un mensaje aleatorio.

Saludos!


Título: Re: Algoritmo inscripcion autenticacion
Publicado por: matake en 2 Diciembre 2016, 22:07 pm
Hola kub0x,

"Mas claro que el agua" !!!
Ahora ya he entendido bien todo.

Fue esta frase que me confundió:
Citar
- Genera un par de claves RSA en el lado del servidor. Esto ya contábamos con ello ¿por qué sino como cifra el usuario la simétrica AES sobre el mensaje aleatorio?

Por esto creí que quieres decir, que tengo que generar las claves del usuario en el servidor de donde deduje yo que luego tendría que mandárselo al usuario.
Ahora si me ha quedado claro que no es así.

Estas semanas intentare armarlo todo en local ya te contare que tal me ha ido.

Saludos y gracias por todo.