Estoy trabajando en un sistema de juegos que usa UnityScript y C # en el cliente y PHP en el servidor. Se utiliza un hash MD5 de los datos más un secreto compartido para verificar que los datos no se hayan modificado en tránsito. ¿MD5 es lo suficientemente bueno para esto? ¿Qué otro algoritmo hash podría usar que funcione en los tres idiomas?
El problema con más detalle
Me he encontrado con un código en un sitio web de la comunidad sobre la popular plataforma de desarrollo de juegos Unity, y ahora estoy trabajando para mejorar MySQL, PHP y la seguridad de ese código.
El código utiliza un valor de "clave secreta" que se comparte entre el cliente y el servidor. Todos los mensajes del cliente incluyen un hash de los datos (por ejemplo, nombre y puntuación) más la clave secreta, que el servidor verifica antes de aceptar los datos. Esto es básicamente una autenticación que los datos pasados no han sido alterados.
Sin embargo, debido a que es MD5, creo que alguien que esté escuchando el tráfico de la red podría encontrar fácilmente la clave secreta y luego publicar los datos que quiero al servidor.
Entonces, mis preguntas son:
- ¿Esta situación actual justifica una mejora? ¿O es este el uso actual previsto de MD5 (a partir de enero de 2017)?
- ¿Existe otro algoritmo de hash que podría mejorar / autenticar aún más esta actividad de comunicación? Tenga en cuenta que el algoritmo debería funcionar en PHP, UnityScript y C #.
El código
-
En UnityScript (lado del cliente):
var hash = Md5.Md5Sum (nombre + puntuación + clave secreta);
-
En C # (lado del cliente):
string hash = MD5Test.Md5Sum (nombre + puntuación + clave secreta);
-
En PHP ( lado del servidor):
$ secretKey = "mySecretKey"; // Cambie este valor para que coincida con el valor // almacenado en el javascript del cliente debajo de $ realHash = md5 ($ _ GET ['nombre']. $ _GET ['puntaje']. $ SecretKey); if ($ realHash == $ hash) { // interactuar con la base de datos}
Más criterios
-
Algunos programadores de Unity use UnityScript (un lenguaje similar a Python con una sintaxis similar a JavaScript en la API .NET) pero no se puede asumir que ninguna biblioteca esté instalada.
-
Los desarrolladores de juegos son no programadores PHP / MySQL tan complejos o el código PHP / C # / Js de terceros probablemente no sería útil.
-
BCrypt es aparentemente imprudente de usar con C #
-
BCrypt necesita una estática salt en este caso (¿quizás derivado de la clave secreta?) pero está destinado a funcionar con una sal aleatoria.
-
PBKDF2 parece preferirse a BCrypt, pero puede ser muy lento, especialmente en dispositivos móviles sin mucha memoria.
-
No se puede esperar lidiar con un servidor seguro (aunque solo sea ...).
-
No sé lo suficiente acerca de la biblioteca de seguridad C # para elegir las mejores opciones de las que se enumeran.
-
Si bien el código descrito tiene que ver simplemente con actualizaciones de puntuación más alta, este código se ha tomado en el pasado, y se usará en el futuro, para transportar todo tipo de datos. , público y privado para varias bases de datos.
-
Tratar con la interoperabilidad del algoritmo hash entre PHP, UnityScript, C # es un obstáculo mayor de lo que había anticipado. Si fuera solo PHP, usaría
password_hash
.
Algunos pensamientos y antecedentes a esta pregunta:
Actualicé el título porque el título editado parecía sugerir que no estaba seguro de cambiar MD5, mientras que saber que debería cambiar MD5 fue una de las razones principales para preguntar la pregunta aquí en primer lugar.
La pregunta original era que quería actualizar las terribles sugerencias de código que se dan en (entre otros lugares) aquí sobre cómo manejar las interacciones entre un juego en una máquina cliente y el almacenamiento de datos en un servidor remoto. . Ten en cuenta que se trata de sugerencias de código para programadores principiantes en Unity y este sitio [ahora] lo gestionan las propias tecnologías de Unity.
Si miras, la pregunta original (enlazada arriba) estaba usando PHPMysql_
funciones (así como una forma inválida bastante cutre de PDO). Sentí que esto se beneficiaría de una reescritura. Vi que el código original también había usado una rutina md5 para codificar los datos deseados. En lo que respecta al reemplazo de MD5, no me había dado cuenta de la vulnerabilidad de los archivos de proyecto compilados o del tamaño / escala del trabajo necesario para que este bloque de código sea más seguro (ya sea en la interacción con el servidor o en el lado del cliente datos). Mi búsqueda original era encontrar un reemplazo adecuado para el MD5 que pudiera funcionar en los diferentes lenguajes requeridos (UnityScript, C #, PHP), ya que era consciente de sus deficiencias. No me había dado cuenta (a juzgar por los comentarios aquí) lo tediosamente fácil que es entrar en archivos exe y obtener datos codificados.Esta pregunta NO se trata de un juego que ' Estoy haciendo, no se trata de Mi proyecto y el código citado que tengo la intención de reemplazar no fue escrito por mí . Leí muchos de los comentarios de que de alguna manera la gente está probando el mensajero, pero esta pregunta surgió de mi propio deseo de mejorar una deficiencia existente en un sitio web de enseñanza wiki. Tengo el mayor respeto por el conocimiento compartido al responder esta pregunta, pero soy consciente de que desde los últimos 6 meses explorando la documentación de Unity y los sitios de aprendizaje, existe una brecha significativa en la seguridad de las aplicaciones locales y el modo multijugador u otras interacciones remotas.
Veo muchos encuestados en los comentarios que afirman que la respuesta dada por George es una mala respuesta, pero responde a la pregunta específica que hice en ese momento. Gracias.
Nota final:
Esta publicación de Blob de los comentarios de Luke Briggs subrayó lo fácil que es un proceso a simple vista para manipular los datos de la aplicación de juegos Unity local. No comprendí en absoluto cómo los archivos locales vulnerables son ...