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 - GonzaFz

#1
Estoy haciendo una aplicacion para capturar el trafico de un programa especifico. En realidad no tengo que serializar paquetes de red, sino simplemente los mensajes que se envian a travez de sockets, en otras palabras el buffer del paquete.

Lo que estoy haciendo basicamente es redireccionando las funciones send y recv a unas propias para luego serializar toda la comunicación de la aplicación.

Estuve probando la libreria Protobuf de Google y es muy facil de usar, el problema es que almacena todos los datos en memoria y hay que serializarlos/deserializarlos todos juntos, y basicamente la memoria va aumentando lentamente.

Yo estaria necesitando una libreria que me permita serializar por partes, es decir, ir añadiendo los paquetes al archivo a medida que van llegando.

La salida que espero es mas o menos así, aunque no necesariamente en json, preferiria datos binarios.
{
     "date": "2018-08-10T17:03:15Z",
     "version": "7.6.1.1",
     "packets":
     [
      {
       "buffer": "xxxxxxxx",
       "date": "2018-08-10T17:18:16Z"
      },
      {
       "buffer": "xxxxxxxx",
       "date": "2018-08-10T17:18:16Z"
      },
      ...
     ]
}


Vi que por ejemplo wireshark usa Cap'n Proto pero no estoy del todo seguro que permita serializar por partes, y mucho menos deserializar solo algunos datos.

Flatbuffers al parecer permite deserializar por partes, pero no estoy seguro si se puede hacer una serialización "por partes" como explique mas arriba.

De cualquier modo, incluso es posible hacer lo que requiero? No se si existe un nombre tecnico para esto, hice una busqueda en google pero no encontre nada. Quizás solo sea posible serializar todo junto, en ese caso no se cual seria el camino ideal para evitar problemas de memoria.

No es algo critico, la aplicacion es para algo muy especifico y personal pero me gustaria saber si hay alguna otra alternativa.

Saludos.
#2
Muchas gracias a ambos. Demore en responder porque estaba procesando todo, mas lo que me respondieron tambien en stackoverflow.

Me han aclarado la mente, tan mal estaba que hasta formule mal la pregunta inicial, en realidad tendría que haber sido sobre como definir quien debe implementar cada requisito del sistema, pero lo que me respondieron me sirvio mucho, la conclusión es que tengo que sentarme a leer sobre patrones, y en particular sobre GRASP.

Supongo que toda mi confusión viene porque en una materia de la facultad nos hicieron desarrollar una aplicación con JavaEE donde las entidades eran solo modelos de datos, y toda la logica estaba ubicada en otra capa. Al parecer esto se conoce como "Anemic domain model".
De ahi que no podia conectar en mi cerebro otra forma de ver la orientacion a objetos, segun wikipedia ese modelo es anti-oop.


NEBIRE, simplemente gracias por el analisis tan completo.

WhiteSkull en cuanto a que Laboratorio tendria que ser una entidad estatica es cierto, segun el escenario el sistema es para un solo Laboratorio/Hospital, de todas formas entiendo que NEBIRE hizo un analisis mas completo, suponiendo algunas otras cosas y por eso su diseño es diferente.
Tambien tenes razon sobre lo de devolver el paciente, me olvide de aclarar que en otro ejercicio me lo pedian que lo incluya, a igual que con los medicos.


Ahora tengo otra duda con respecto al diseño/arquitectura como lo plantee inicialmente, dado que el sistema debe poder devolver un medico y un paciente si el usuario se lo pide, y suponiendo que uno quiere saber los analisis de un paciente y los analisis que un medico solicito.
Cuales serian las formas correctas de modelar esto?

  • 1- Podria hacer que paciente y medico conozcan cuales son los analisis en los que participan, pero para ello tendria que implementarles un metodo addAnalisis() a ambos, y eso implica que no tengo forma de contolar que al agregar un analisis a un paciente, tambien se lo haga al medico que lo solicito. Es decir, podria, pero nada quita que en alguna parte del programa alguien llame a Paciente::addAnalisis() y pase por alto hacerlo tambien al medico, y que paciente se encargue de cargar al medico y viceversa me generaria problemas de acoplamiento
  • 2- Lo de arriba me lleva a pensar que podria generar una clase que funcione como repositorio de analisis, y que nunca este expuesta fuera de Laboratorio, Paciente y Medico. De esta forma, al llamar a Laboratorio::addAnalisis(), cargaria el analisis al repositorio, y luego Paciente::getAnalisis() haria una consulta al repositorio. De esta forma me evitaria tener los metodos Laboratorio::getAnalisisByPaciente() y Laboratorio:getAnalisiByMedico()
    En parte seria plantear lo mismo que puse en mi primer post pero de una forma mas elegante, sin sobrecargar demasiado a Laboratorio
#3
Estoy estudiando diseño de sistemas y me estoy comiendo la cabeza con la definición de algunos métodos. Lo que me cuesta identificar es quien debe llevar a cabo algunos métodos.

El escenario con el que estuve practicando es muy simple: "Un laboratorio de analisis clinicos ha comenzado el desarrollo de un sistema para la registracion de los analisis realizados por sus pacientes y el profesional que los solicita".

Partiendo de eso identifique cuatro clases: Paciente, Medico, Laboratorio y Analisis.

  • Paciente: representa una persona que se atiende en el laboratorio
  • Medico: representa un profesional de la salud
  • Analisis: representa un estudio solicitado por un medico especifico para un paciente determinado
  • Laboratorio: representa la clinica donde los medicos realizan analisis a los pacientes

De ahi pase a realizar el digrama de clases UML teniendo en cuenta que:

  • Un paciente puede tener muchos analisis. El paciente debe conocer los analisis que se realizo
  • Un medico puede haber solicitado muchos analisis. Debe tener cuenta de los analisis que requirio



Mi problema es que ese diagrama no me convence porque no tengo forma de asegurar que cuando se ejecuta paciente.addAnalisis(a), el analisis a ya haya sido cargado en el laboratorio.

Para ponerlo de otra forma, cualquiera que tenga acceso a un objeto Paciente podria agregar un analisis al paciente sin cargar ese mismo analisis al laboratorio y/o medico correspondiente. Lo mismo pasaria para un medico, cualquiera que tenga una referencia al medico podria cargarle un analisis sin tambien agregarlo al laboratorio ni al paciente. Esto supongo que generaria mucha inconsistencia en el sistema.

Yo podria implementar esa logica en Laboratorio::addAnalisis(a: Analisis), pero de nuevo, nada impide que alguien se salte esto y lo agregue manualmente.


Entonces mi otra solucion fue elminar los metodos addAnalisis y getListaAnalisis tanto de medico como de paciente, y luego agregar dos metodos a Laboratorio:

  • getAnalisisByPaciente(p: Paciente): Analisis[0..*]
  • getAnalisisByMedico(m: Medico): Analisis[0..*]

En este caso solo podria agregar analisis desde la clase Laboratorio, y asi implementar toda la logica necesaria en un solo lugar. Verifico que el medico y paciente asignado al analisis existan y luego lo agrego a la lista.
El problema es que ahora no estaria reflejando lo de que un paciente y un medico tienen que llevar cuenta de los analisis realizados.

Entonces no se como es la forma correcta de resolver esto.

Quizas no me deberia importar que alguien pueda llamar a Paciente.addAnalisis() y me estoy complicando por nada

Perdon por la falta de coherencia en todo esto pero tengo una ensalada en la cabeza y no se como explicarlo mejor. Saludos
#4
Mira, probe la compresion GZip de .Net y por lo que llegue a leer, a fondo es simplemente la misma que la de Deflate (implementada en .Net) pero con algunos agregados mas como checksum y otros detalles.

GZip me lanza un error de numeros magicos.
Deflate encuentra errores en el bloque.

Tambien probe una libreria de ZLib (DotNetZip) y tampoco me descomprime.

Intente hacerlo a la inversa, poniendo la cadena descomprimida y comprimiendo para analizar si arroja un resultado similar pero no, en todos estos casos en la cadena comprimida resultante no hay ninguna cadena literal (como si las hay en el algoritmo que estoy usando, si se ven las imagenes, en el paquete comprimido hay fechas, nombres, etc).


EDIT:
Como nadie me supo decir (tambien pregunte en otro foro pero no me respondieron) decidi implementarlo yo mismo.
Lastimosamente, ademas de que todavia el codigo no esta listo (me falta mucho pero esta encaminado), no se si voy a liberarlo o no asi que todavia no lo voy a compartir. Si algun dia lo libero voy a actualizar este tema y dejar el link para que puedan ver por si necesitan hacer algo similar.
(No lo libero por no perjudicar a los desarrolladores del juego, hacerlo daria facilidad a cualquier oportunista de aprovecharse de todo lo que logre hasta ahora, y mi objetivo no es perjudicar al juego).

De todas formas mi idea fue implementarlo al estilo como .net implementa DeflateStream y GZipStream, para que sea facil luego utilizarlo en cualquier situacion (ademas de elegante y aprender como los grandes escriben codigo).
En el repositorio de github de dotnet: https://github.com/dotnet/corefx/blob/master/src/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs

Luego de ahi pueden ir sacando que otras clases se necesitan.

Pero yo no me base en eso, utilice otro similar, de una libreria opensource (SharpZipLib) que implementa de manera muy similar, aunque quizas mas simple.
https://github.com/icsharpcode/SharpZipLib/blob/master/ICSharpCode.SharpZipLib.Shared/Zip/Compression/Streams/InflaterInputStream.cs

Ese seria el stream para descomprimir, y luego en el mismo directorio esta el DeflaterInputStream que es el stream a comprimir. Lo mismo, de ahi van sacando las otras clases que necesitan.


Cualquier duda me consultan, creo que mi reproduccion del algoritmo de descompresion fue un exito, ahora me faltaria desarrollar el de compresion.

Saludos.

#5
EDIT2: El algoritmo resulto ser LZO.
Cualquiera que necesite informacion sobre su funcionamiento hay algo aca:
https://www.kernel.org/doc/Documentation/lzo.txt

Lastimosamente sin ingenieria inversa no se puede obtener informacion de como funciona, en ningun lado hay una especificacion oficial.



Buenas, estoy en el proceso de hacer ingenieria inversa al protocolo de red de un mmorpg.

Algunos paquetes que suelen ser muy largos se comprimen con un algoritmo que estuve analizando pero no puedo determinar cual es (el cliente solo los descomprime, nunca comprime un paquete para enviarlo, por lo tanto no tengo acceso al proceso de compresion)
Todavia sigo creyendo que es una variante del LZ77 pero no logro dar con cual, lei el funcionamiento de varias pero no encuentro un parecido a ninguna (y tampoco creo que sea viable ponerme a probar todas porque seria dificil dar con el resultado exacto).

Tambien utilice extensiones del ida pro pero no tuve buenos resultados. Se menciona Deflate y unlzx pero ninguna de las referencias es utilizada dentro del proceso de descompresión.

Voy a intentar explicar lo mas claro posible como funciona el proceso, a ver si alguno me puede dar una mano. Se que seria facil simplemente reconstruirlo tal cual me muestra el hex rays y listo, pero mas me mata la curiosidad de saber cual es y quisiera poder implementarlo al 100%



Detalles:
Por lo que pude observar del algoritmo siempre trabaja sobre el buffer de entrada y de salida. Nunca utiliza alguna tabla/string o lo que fuese externo a estos dos.
Utiliza punteros (tal como el lz77 y sus variantes) para indicar el desplazamiento hacia atrás desde la posición actual. La información que tienen los punteros esta definida a nivel de bits.
Siempre que descomprime lo hace en base a lo que fue escribiendo en el buffer de salida. Del de entrada solo va tomando los pares de bytes que representan los punteros.
Desde mi parecer la descompresión es obligatoriamente secuencial, no hay posibilidad de saber dinamicamente donde hay otro puntero, al menos sin haber analizado los punteros anteriores.
Al comienzo de la cadena comprimida siempre hay un par indicando que es lo que viene.
El factor de compresion, al menos para el unico paquete que analice (lo hice varias veces pero siempre trae la misma informacion) es de casi el 50%.


Algoritmo:
Voy a intentar explicarlo a grandes rasgos (es posible que me saltee algunas partes).
Si quieren ver el algoritmo en c sacado de hex rays lo pueden hacer aqui:
https://gist.github.com/FYGonzalo/a4118d35620d48bacea2253d5aa48e6d

Las variables las renombre yo, puede que alguna tenga un nombre que no la represente. Tambien hay algunos comentarios del codigo, igual no se si sera mas entendible leer mi "pseudocodigo" o el codigo directo del hex rays.

Mas abajo adjunto una parte del proceso de descompresión de un paquete.

Al comenzar analiza el primer byte (de ahora en mas firstByte) del buffer de entrada (de ahora en mas inputBuffer).
Si este es mayor a 0x11 (17): // Significa que hay bytes descomprimidos y se deben copiar tal como estan
   Le resta 0x11 (17) al firstByte y el resultado indica la cantidad de bytes por copiar.
   Avanza una posicion en el inputBuffer (la siguiente al firstByte) y copia lo que indica el resultado anterior.
   Dependiendo cuanto fue el resultado salta a un label donde sigue haciendo analisis del par de bytes.
Sino
LABEL 1
   Lee en una variable "secondByte" el segundo byte del inputBuffer
   Si el firstByte es menor a 0x10 (16)
       Si el firstByte es nulo
           Si el secondByte es nulo
               -----
           firstByte = secondByte + 15
       Copia una DWORD del inputBuffer al outputBuffer y avanza los punteros (de ambos buffer) 4 posiciones
       Asigna a un contador el valor de firstByte - 1
       En base al valor del contador itera copiando bytes del inputBuffer al outputBuffer (sin modificarlos)
       Vuelve a leer del inputBuffer otro par (firstByte & secondByte)
       Si el firstByte es menor a 0x10 (16)
           ------
   Mientras (1)
       Si firstByte es mayor a 0x40
           Obtiene un puntero al outputBuffer retrocediendo ((-((firstByte >> 2) & 7) - 1) - secondByte * 8) posiciones


Pausa. Aca se observa una de las situaciones en donde se opera el par en base al valor de sus bitss.
En un caso que detallo mas abajo, el par que se trabaja es (4C, 01)
El valor en bits de 4C es: 0100 1100
Aplicamos el shift de 2 posiciones: 0001 0011
Aplicamos el and 7: 0001 0011 & 0000 0111 = 0000 0011
Sumamos 1 (en realidad es resta, pero son ambos negativos asi que lo obviamos): 0000 0100.

La conclusion que saque de esta operacion (y de otras donde se repite) es que en el firstByte, cuando es mayor o igual a 0x40, hay 3 bitss que indican parte del desplazamiento.
En este caso seria: 0100 1100
Pero como luego se le suma 1 sabemos que el primer termino, de la operacion compleja indicada en la ultima linea de codigo mas arriba, dara como resultado un valor entre 1 y 8 (no mas ni menos).

Luego simplemente se suma (nuevamente, es una resta pero al ser todos negativos lo obviamos) el valor del secondByte (sin importar cual fuere) multiplicado por 8.
Es decir que al final vamos a retroceder en el outputBuffer la cantidad resultante de esta suma.


           Avanza el inputBuffer posicionandose en el byte siguiente al par que estamos analizando
           Determinamos la cantidad de bytes por copiar* aplicando ((firstByte >> 5) - 1)        


Nuevamente nos detenemos aqui.
Recordemos que el firstByte actualmente tiene el valor 4C que en binario es: 0100 1100.
Aplicamos el shift 5 posiciones a la derecha: 0000 0010
Le restamos 1: 0000 0010 - 0000 0001.

La conclusión de este segmento es que los 3 bitss de mayor peso del firstByte (siempre que este sea mayor a 0x40) indican una cantidad de bytes por copiar*.
*En realidad no indica la cantidad total de bytes por copiar. Obligatoriamente al llegar a este punto se copian al menos 2 bytes (lo veran en las siguientes lineas de codigo), pero indica la cantidad de bytes, luego de haber copiado 2 obligatorios, que se deben copiar.


           Copiamos dos bytes obligatorios del outputBuffer (basados en el puntero que obtuvimos anteriormente hace 4 lineas de codigo)
           Luego copiamos tantos bytes del outputBuffer como indique la operacion anterior.
           Luego saltamos a otro label donde aplicamos una and entre el firstByte y 3. El resultado indica la cantidad de bytes (planos) del inputBuffer por copiar. En caso de que sea 0, volvemos al Label 1, sino continuamos en el while.


Nuevamente se opera a nivel de bits.
Al aplicar la operacion and entre el valor de firstByte y 3 (0000 0011) lo que hacemos es analizar los dos bits de menor peso del firstByte.
Es decir que ahora como conclusión entendemos que significa completamente el firstByte cuando es mayor o igual a 0x40:
0100 1100: Indican parte de la cantidad de bytes a copiar del "diccionario" (recordemos que se le resta 1) y obligatoriamente se copiaban 2
0100 1100: Indican parte del desplazamiento hacia atras en el outputBuffer donde se encuentra la cadena descomprimida (recordemos que se le suma 1 y luego 8 * secondByte)
0100 1100: Indican la cantidad de bytes planos del outputBuffer que debemos copiar luego de haber copiado los "descomprimidos".


       Si el firstByte es menor a 0x20 (32)
           Break (sale del while y creo que termina con algunas operaciones)
       (Si el firstByte es menor que 0x40 pero mayor o igual a 0x16 - Condicion no especificada pero se llega a este punto debido a esa situacion)


En este caso se da una situacion particular. Es como si se invirtieran la responsabilidad de los bytes del par y ahora el segundo byte (secondByte) indica los desplazamientos hacia atras en el outputBuffer y el firstByte los bytes por copiar.


           Se obtiene una "cantidadCopiar" haciendo firstByte & 0x1F


Aqui nuevamente se vuelve a trabajar a nivel de bitss.
Un caso que analice en el cual se entraba a este punto es con el par (2A, C8).
Como dijimos anteriormente cuando el firstByte es menor a 0x40 pero mayor o igual a 0x20 se invierten las responsabilidades.
Sabemos que 2A es: 0010 1010
Y 1F: 0001 1111

Asi que al aplicar la operacion and entre ambos lo que estamos haciendo es recuperar los 5 bitss de menor peso del firstByte.
El resultado sera 0000 1010


           Si cantidadCopiar es nula
               Si secondByte es cero
                   -----
               cantidadCopiar += secondByte + 31 (decimal)
           Obtenemos un puntero al outputBuffer con un retroceso desde la posicion actual determinado por ((secondByte >> 2) + 1)


Nuevamente se trabaja con bitss.
Recordemos, secondByte es C8: 1100 1000
Aplicamos el shift: 0011 0010 (50 decimal)
Restamos 1: 0011 0001 (49 decimal)


           Avanzamos el inputBuffer 2 posiciones (nos saltamos un byte despues del par que estamos analizando)
           --- Se aplica una operacion rara dada una condicion que nunca vi que fuese verdadera bajo el inputBuffer de prueba que estoy analizando ----
           Copiamos una DWORD de la posicion que indica el puntero que definimos unas lineas atras (del outputBuffer) y lo pegamos en la posicion actual del outputBuffer. Es decir, copiamos una DWORD "descifrada" del outputBuffer a la posicion actual del outputBuffer (basicamente buscamos en el diccionario la palabra y la pegamos)
           Avanzamos 4 posiciones (por el DWORD) en los punteros a ambos buffers.
           Disminuimos la cantidadCopiar en 2
           Hacemos un bucle copiando la cantidad de bytes que indique "cantidadCopiar"

           Nuevamente (como el caso de mayor o igual a 0x40): (Basicamente es un label que no lo puse como tal)
           Aplicamos un and entre el byte que indica el offset (ahora es el secondByte, en el caso anterior habia sido firstByte) y 3. El resultado indica la cantidad de bytes "planos" restantes por copiar del inputBuffer al outputBuffer.


Otra vez trabajamos a nivel de bits.
Al aplicar el and al secondByte (0xC8) lo que estamos haciendo es recuperar los 2 bitss de menor peso.

Recapitulando ahora conocemos toda la informacion que trae el secondByte:
0011 0010: Indican el desplazamiento hacia atras en el outputBuffer (recordemos que se le resta 1)
0011 0010 Indican la cantidad de bytes "planos" que deben copiarse del inputBuffer al outputBuffer, luego de haber copiado los del diccionario indicados por el puntero.


           En caso de que este resultado sea mayor que 0, copiamos los bytes que indican y seguimos dentro del while.
           En caso contrario (sea igual a 0), volvemos al LABEL 1.

Ya cuando se sale de todo este bucle (unicamente por el Break de que firstByte < 0x20) se hacen operaciones para finalizar, se copian los bytes restantes y algun que otro detalle.
Se devuelve la longitud del buffer de salida.


Descompresion de un paquete real:
Lo pueden ver aqui, hay imagenes y una explicacion del proceso hasta cierto punto (no lo cargo al post porque se haria mucho mas largo de lo que ya es).
http://imgur.com/a/kuQkl





Y eso es todo lo que pude obtener, la verdad es que hay algunos detalles mas del algoritmo pero no llegue a analizarlos porque mi principal objetivo es determinar que estandar de compresion (si es que es un estandar) es el utilizado.

Espero no haberlos aburrido, y que me puedan dar una mano, me costo mucho trabajo hacer la ingenieria inversa y luego un poco mas redactar todo el post y juntar las pruebas.

Saludos.
#6
Hola, gracias a los dos por responder.

Entiendo la idea que me plantean, es basicamente como hice mi solución actual (aunque en un futuro me gustaria cambiar).
El problema es que yo estoy haciendo un packet sniffer, y para usar esta idea tengo que mantener una lista con todos los paquetes hasta que el usuario decida terminar el programa.
No pasara nada si son unos minutos, pero si se deja mucho tiempo el uso de memoria seria excesivo e ineficiente (porque no hay razon de tener todos los paquetes en memoria cuando la idea es simplemente escribirlos a un archivo).

Es decir que lo que quiero lograr es que cada vez que se envie o reciba un paquete, escribirlo en un archivo y olvidarme de el.


Entiendo que esto lo puedo hacer manualmente con XDocument pero me interesa saber si no me estaré pasando por alto algo o mi idea de que la lista ocupara mucha memoria es erronea, ya que no soy de programar mucho.
#7
Estoy escribiendo un Packet Sniffer y lo que quiero hacer es cada vez que capturo un paquete, serializarlo a un archivo XML para poder procesarlo mas tarde.

Estuve analizando usar XmlSerialization que fue lo primero que encontre en google pero mi problema es que, por lo que vi, esta pensado para que cada vez que se serializa un objeto, este se guarde en un nuevo archivo (lo digo por el hecho de que escribe el archivo completo, incluyendo el namespace y etc). Si utilizo esto lo que ocurre es que tengo que mantener en memoria todos los paquetes que vayan llegando hasta que el usuario quiera dejar de capturar y luego recien escribir el archivo (uso excesivo de memoria).

Mi primera idea fue que cada vez que llegue un paquete, escribirlo en el archivo y liberar ese objeto, por lo que me parece que XDocument puede ser util en este caso, solo que voy a tener que escribir manualmente el proceso de serialización.

Basicamente lo que me gustaria saber, si ya manejaron la serialización xml, como me recomiendan haga este proceso.

Saludos
#9
Buenas a todos.

Tengo un conocido que trabaja (no pertenece al area de sistemas) en una empresa de transportes (no quiero dar muchos detalles para no tener problemas) que esta preocupado porque se entero que en una ciudad estan cargando tarjetas de transporte de otra empresa de forma ilegal y tiene dudas sobre si no esta pasando lo mismo en su empresa.

Como entusiasta que soy me puse a investigar sobre el tema y tengo entendido que las tarjetas que usan son las Mifare Classic de 1k. Lei por completo el tema que hay en este foro del año 2009 y segui googleando, obviamente me entere que son facilmente hackeables en poco tiempo.

Le comente todo lo que encontre y me dijo que hablo con el gerente de sistemas y le dijo lo siguiente:
"Me dijo que [CIUDAD DE LA EMPRESA DONDE TRABAJA] es distinto porque modificaron la estructura de la tarjeta y que el código son 6 dígitos por lo que se tardaría 11 años en encontrar la clave.. Y que además tiene una firma que calculo son otros dígitos mas.
Pero la de [OTRAS CIUDADES QUE USAN MIFARE] dijo el que pudo romper en 4 dias, Y el teniendo el primer numero, saco por fuerza bruta"

Por lo que es obvio que cuando se refiere a que modificaron los 6 digitos hace referencia a una de las claves a o b de los sectores y que cuando habla de fuerza bruta hace referencia al metodo "darkside"
Y calculo que cuando se refiere a la firma es algun metodo de crifrado sobre la info del sector que utilizan.

Ahora, la cosa es que este conocido dice que el area de sistemas es un tanto soberbio y que no esta seguro de todo lo que le dicen, entonces le explique los metodos de seguridad que considero que pueden tener pero al fin y al cabo la mayoria son corrompibles.

Lo unico probablemente seguro seria que la informacion de la tarjeta, cada vez que se realice una transaccion se valide con un servidor, pero siendo transportes en constante movimiento creo que no se pueden valer de una conexion en tiempo real todo el tiempo.
Y lo de que se encuentre cifrado tampoco es muy claro porque tranquilamente podria cargar la tarjeta, guardar el dump y cuando se termine el credito volver a pegar ese dump (a menos que tenga algun tipo de seguridad adicional).

Al fin y al cabo lo que me gustaria saber es si alguno de ustedes conoce algun caso practico donde se le haya agregar mayor seguridad a las tarjetas mifare classic, porque lo que me hace ruido es que si en paises importantes como chile o mexico (o incluso paises europeos) se pudo hackearlas, entonces que tanto pudo haber hecho una empresa de por acá como para darle esa seguridad a las tarjetas mifare classic que al final nunca llegaron a tener.

Soy tan solo un chico de 21 años y siento que es muy probable que le este llenando de paranoia a mi amigo (no me creo tan inteligente como para poder burlar al area de sistemas de una empresa importante) pero es que hay muchas cosas que me hacen ruido.

Mi objetivo es basicamente saber si existe la chance de que ellos (el area de sistema) le haya agregado la seguridad necesaria a la tarjeta o solo lo dice para que mi conocido no rompa los huevos.
Probablemente la unica forma de saber esto sea que yo me ponga a probar pero no tengo el lector.

Saludos y gracias de antemano.

#10
Hola.
En la facultad nos pidieron que desarrollemos una aplicación web un poco compleja, básicamente para que utilicemos Java EE 7 (JPA, JDBC, Servidor de mail, etc).
Estuve leyendo y viendo algunos videos y todavia no logro imaginarme como sera mi proyecto.
Por lo que lei se recomienda utilizar maven para la gestion y estructuracion del proyecto por lo que busque y me encontre con esto:
https://maven.apache.org/plugins-archives/maven-archetype-plugin-1.0-alpha-7/examples/j2ee-simple.html

Y lo que me marea es que no se como organizo mi aplicacion bajo esa estructura. Digo esto porque me vi un tutorial (no muy bueno) de codigo facilito y en primer lugar habla sobre crear un sistema bajo java ee pero empieza el proyecto como un web application solamente, y despues habla sobre el mvc y lo unico que hace es dividir el proyecto asi
.
|
|--WebPages
|  |--index.jsp
|
|--SourcePackages
|  |--modelo
|  |  |--conexion.java
|  |
|  |--servlet
|  |  |--controlador.java

Y no me parece que un proyecto de Java EE se diseñe asi, no se exactamente como explicarlo pero siento que no es la forma de encarar un proyecto.

Alguien me podria encaminar un poco? Gracias