Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - kub0x

#451
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:

CitarSin 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 (javascript) [Seleccionar]
   function _rsasign_signStringWithSHA256(s)
   {
       var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), 'sha256');
       var biPaddedMessage = parseBigInt(hPM, 16);
       var biSign = this.doPrivate(biPaddedMessage);
       var hexSign = biSign.toString(16);
       return hexSign;
   }


¿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.

CitarLos 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!
#452
CitarCryptoJS 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 (javascript) [Seleccionar]
my.generateAESKey = function()
    {
        var key = new Array(32);
        var r = new SecureRandom();
        r.nextBytes(key);
        return key;
}


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.

CitarOk 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 (javascript) [Seleccionar]
function _rsasign_signStringWithSHA256(s)
{
    var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), 'sha256');
    var biPaddedMessage = parseBigInt(hPM, 16);
    var biSign = this.doPrivate(biPaddedMessage);
    var hexSign = biSign.toString(16);
    return hexSign;
}


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 (javascript) [Seleccionar]

function _rsasign_verifyHexSignatureForMessage(hSig, sMsg)
{
    var biSig = parseBigInt(hSig, 16);
    var result = _rsasign_verifySignatureWithArgs(sMsg, biSig, this.n.toString(16), this.e.toString(16));
    return result;
}


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!
#453
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 (javascript) [Seleccionar]
// The passphrase used to repeatably generate this RSA key.
var PassPhrase = "The Moon is a Harsh Mistress.";

// The length of the RSA key, in bits.
var Bits = 1024;

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:

CitarEncryption

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.

CitarAquí 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!
#454
Cita de: matake en 23 Noviembre 2016, 06:10 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!
#455
Cita de: matake en 23 Noviembre 2016, 05:04 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.

Cita de: matake en 23 Noviembre 2016, 03:18 AM
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!
#456
Cita de: matake en 23 Noviembre 2016, 03:18 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!
#457
Cita de: ancasu en 23 Noviembre 2016, 00:33 AM
Hola, navegando con shodan encontré cierto servicio que es vulnerable ubicado en cierto país de oriente, como reportar la vulnerabilidad si aparece la IP, el país , la organización y otra información; como busco la persona adecuada, para reportar?. o si mejor dejo así?

gracias!

Localiza una dirección de correo electrónico asociada al servicio, al poder ser, relacionada con su administración, y mándales un correo sólo informándoles de que has encontrado una vulnerabilidad en su servicio. Si ellos te responden de forma educada e interesándose por el fallo, entonces de ti depende llegar a un acuerdo o simplemente darles la información si así lo desean.

Pero nunca des la info sin preguntar y sin respuesta previa del servicio. Si te sientes incómodo, puedes enviar el correo desde una dirección anónima mediante una red anónima.

Saludos!
#458
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.

CitarInspirado 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 [latex]7.28951401\cdot10^{14}[/latex] 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 [latex]10^{30}[/latex] 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 [latex]P_{final} = 429596212621582171952785642712[/latex] 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 [latex]P_{final}[/latex] pero como la inicial la desconoce, sigue sin sacar nada en claro. Entonces reconstruye [latex]P_{final}[/latex]:

Supone que [latex]P_{1} = 42[/latex] 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 [latex]P_{final}[/latex] 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 [latex]7.28951401\cdot10^{14}[/latex] 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!
#459
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 [latex]\frac{1}{7}[/latex]. 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) = [latex]44^{3}= 84184[/latex]  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) [latex]\frac{44!}{3! \cdot 44!}= 79464[/latex]  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 [latex]P_{6}=6!= 720[/latex] 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!
#460
Criptografía / Re: Pgp cifrar partición unidad
21 Noviembre 2016, 18:21 PM