Sugerencias para(semi) asegurar altas puntuaciones en el juego Flash/PHP
actionscript-3 actionscript (7)
... He leído algunos temas aquí que han discutido varios métodos y solo estaba buscando comentarios sobre una solución propuesta que se nos ocurrió. En uno de los hilos se publicó un comentario que recomendaba una clave pública / privada que sonaba genial, esto es lo que estábamos pensando ...
Lado del cliente: 1. La clave se almacena dentro de Flash swf, que se cifra con una herramienta de terceros. 2. El puntaje alto es hash junto con el valor de puntaje alto (EX: md5 (''ourSecretKey'' + 200)) 3. Este valor se envía a través de AMF a un script PHP en el servidor, junto con el puntaje alto (200)
Lado del servidor: 1. El servidor recibe los datos y los hashes de la puntuación alta pasada (200) + clave secreta (''ourSecretKey'' almacenada en el servidor y en Flash) y comprueba contra el hash aprobado si el valor es una coincidencia que permite puntuación alta para ingresar, de lo contrario, FALLA.
Sé que esto no es una solución infalible, pero ¿sería aceptable? Quiero decir, ¿esto sería suficiente seguridad en un formulario de puntaje alto para un simple juego Flash en línea? ¿Pensamientos?
¡Gracias de antemano!
Para un valor ridículamente corto (es decir, valores <64 caracteres), MD5 como un hash se vuelve ineficaz debido a los ataques de tabla de arcoiris, y como el valor que está enviando se compartirá por el cable, todo lo que tienen que hacer es utilizar el secreto compartido (y tienen un producto conocido para trabajar)
Como tal, eso no es clave privada de clave pública. su secreto compartido meramente.
Además, tenga en cuenta que este secreto compartido estará en su archivo flash que envíe al usuario, que actualmente se desmonta trivialmente y que su "secreto" ya no es un secreto.
Desea un mecanismo de desafío y respuesta con la firma criptográfica adecuada, donde se asigna una nueva clave de firma para cada juego del servidor, y no se pueden enviar múltiples puntajes con la misma clave de firma. (Para protección adicional;))
- El usuario comienza el juego. Se requiere la clave de firma. (la clave del signo se produce a partir de otra tecla a la que no pueden acceder).
- La puntuación se firma con la tecla de signo, y luego se envía
- Verifica el valor del signo con la clave que les enviaste.
- Descartas la clave de firma que les enviaste.
Sin embargo, todavía tiene el problema de que no tiene forma de evitar que se manipule el sistema de puntuación real. Alguien lo suficientemente inteligente podría simplemente aplicar ingeniería inversa a su objeto SWF e inyectar un nuevo código que simplemente establezca el puntaje en su valor elegido.
Blockquote Finalmente, solo tuve que comentar sobre su elección de algoritmo hash: MD5 es un gran algoritmo hash para aquellos que todavía viven en los noventa. Para el resto de nosotros recomiendo SHA-2 o al menos SHA-1.
Bah, sabía que debería haber mencionado a SHA :)
Si utilizo algo así como una aplicación de cifrado swf para encriptar el código swf, ¿no al menos eso dificultaría un poco más la obtención de la clave almacenada en Flash? Pensaría que sin esa clave (o al menos sin llegar a ella fácilmente) sería un gran dolor descubrir qué se estaba utilizando para generar el hash que se envía al servidor.
Algo así es lo que estaba pensando: SWF Encrypt
Gracias a todos nuevamente por estas respuestas, esto es increíblemente útil. Ah, y esto solo será un simple juego Flash enviado por un cliente a los clientes, algo divertido para pasar el tiempo en el trabajo durante las vacaciones.
Si la distribución de tu juego es limitada y no hay dinero real / recompensa involucrado para que los jugadores ganen, tu esquema original es probablemente suficiente.
Usar SWF Encrypt probablemente hará que sea un poco más difícil extraer la clave, y podría ser una buena herramienta incluso en un sistema más avanzado. Pero si tienes un esquema de clave público / privado real (por ejemplo, RSA), es realmente un punto discutible ya que la clave pública no es un secreto, se supone que no es así. Aún así, para evitar que la mayoría de la gente edite el código y altere el sistema de puntuación, SWF Encrypt es probablemente una buena opción.
Solo para volverte un poco más paranoico, también escribí lo siguiente:
El problema con SWF Encrypt, como con la mayoría de las otras herramientas similares, es que todavía debe ser posible ejecutar el script en una máquina (posiblemente comprometida). Entonces, toda la información debe estar disponible en dicha máquina. Compare eso con un uso clásico de la criptografía, enviando mensajes:
Cuando envía un mensaje cifrado, generalmente confía en el origen y el destino, por lo que ambos tienen la clave para descifrar el mensaje. En lo que no confías es en el servicio de mensajería, o al menos no en que tus enemigos no intercepten al servicio de mensajería. Entonces el servicio de mensajería no tiene su clave y su mensaje es seguro.
Su problema es que en su caso confía en el destino (usted) pero no en el origen (el cliente) o viceversa. Aún necesita la fuente para encriptar el mensaje, ya que confía aún menos en el servicio de mensajería. Entonces la fuente necesita tener toda la información para encriptar y descifrar los mensajes para poder funcionar. Tu problema es que no puedes ver la diferencia entre una "buena" fuente y una "mala" fuente.
Lo que quiero decir es que, dado que el código aún debe poder ejecutarse en un cliente, la información para hacerlo debe estar completamente disponible, aunque posiblemente en forma oculta. Un hacker podría, por ejemplo, crear su propio compilador de ActionScript que transforma el código ofuscado de ActionScript en algo legible y hacer los cambios apropiados. Difícil pero definitivamente factible.
Sin embargo, este nivel de ataques sofisticados probablemente no sea un problema para usted, si tiene una distribución limitada y no hay una verdadera recompensa para ganar.
No veo ninguna ventaja de usar la solución, mencionó Kent. Como cliente, puedo solicitar esa clave creada del lado del servidor. Ok, no puedo usarlo más de una vez, pero no tengo que ... cada vez que lo necesito, solo lo pido.
- Entonces solicito la clave.
- Hacer mi propia puntuación más alta
- Hash the highscore con la tecla.
- Envía la puntuación más alta al servidor
- El servidor usa la clave enviada para recuperar la mejor puntuación.
Guau
Soluciones bastante duras 8).
Implementé un sistema como este una vez. Aunque no funcionará para todos los juegos que hay ...
Deberías volver a jugar el juego en el servidor. Cuando el usuario juega, usted almacena "cambios de estado" y luego simplemente lo alimenta a su juego en algún tipo de modo de "reproducción".
Hay una y solo una forma 100% funcional de encriptar los puntajes: grabar la repetición.
Pero no solo CUALQUIER repetición, idealmente solo debería registrar las pulsaciones de teclas del usuario y el espacio entre ellas. De esta manera, incluso si alguien manipuló la fuente o dinámicamente con la RAM, la reproducción reproducida en el servidor encontrará el problema.
Desafortunadamente, esta solución requiere una gran cantidad de trabajo para ser posible. Para simplificar, puede validar manualmente todos los puntajes (o los mejores puntajes) y está contento. Sin embargo, debes evitar algunas cosas:
- Generador aleatorio predeterminado, necesita un generador de semillas que siempre da los mismos números aleatorios para la semilla dada;
- Sin tiempo delta, lo siento;
- Funciones trigonométricas personalizadas (no estoy 100% seguro, escuché una vez que pueden dar resultados ligeramente diferentes en diferentes computadoras);
Y posiblemente más.
Esta defensa es, sin embargo, simplemente irrompible. Y lleva tiempo codificar: D.
La respuesta a tu pregunta es, depende. Depende principalmente de la popularidad estimada de tu juego.
Desde una perspectiva de seguridad, su solución es tan segura como enviar la puntuación más alta en texto sin formato. Lo que estás haciendo aquí se llama seguridad por oscuridad, que, de acuerdo con lo que escuchas, puede tener sus beneficios en algunos casos. En este caso, es probable que Joe, el usuario promedio, no sea capaz de descifrarlo él mismo. Para cualquier persona con alguna habilidad l33t h4xxor, es mejor que lo envíe todo en texto sin formato. Si todo lo que quieres es detener a Joe, entonces es suficiente, al menos hasta que alguien cree un cliente falso para que Joe lo descargue (lo que dependiendo de la popularidad de tu juego podría tomar de unos días a nunca (o más rápido si es Guau)).
Una mejor solución es la dada por @Kent Fredric. Sin embargo, como dice, no resuelve el problema de que alguien cree un cliente falso. Una solución a eso podría ser algo como esto:
- En cada acción, un jugador puede realizar una identificación.
- Almacene cada acción que realiza el jugador en una lista de identificadores.
- Cuando el juego termina, califique la puntuación, la lista de acciones y encripte con la clave pública recibida del servidor. (ver la publicación de Kent Fredric para detalles sobre esto)
- Envíe el hash cifrado (comúnmente denominado firma digital) al servidor junto con el puntaje y la lista de acciones realizadas.
- Deje que el servidor "juegue" el juego de acuerdo con las acciones de la lista.
- Verifique que se obtuvo el mismo puntaje.
- Verifique que la firma digital sea correcta.
- Actualizar la lista de mejores puntuaciones del servidor.
Esto garantizará dos cosas:
- El puntaje proviene del cliente correcto.
- La puntuación es correcta en lo que respecta al juego jugado.
Pero todavía hay una falla grave en este esquema. No hay manera de saber que el juego realmente se jugó realmente. Si el cliente está comprometido, la lista podría ser simplemente un prefabricado de un "juego perfecto" que se envía al servidor. No es posible alterar directamente el sistema de puntuación, pero con el esfuerzo suficiente, es probable que alguien pueda crear una lista de acciones que comprenda un "juego perfecto".
Sin embargo, da una garantía un poco más fuerte que simplemente usar la solución en la publicación de Kent Fredric. Para resolver todo el problema, significa que debe validar el cliente de alguna manera. Esto es muy difícil ya que la mayoría de las formas de hacerlo son fácilmente eludidas.
Finalmente, solo tuve que comentar sobre tu elección del algoritmo hash: MD5 es un gran algoritmo hash para aquellos que aún viven en los noventa. Para el resto de nosotros recomiendo SHA-2 o al menos SHA-1.