Domanda:
Come affrontare la sostituzione di md5 per il trasporto dei dati di gioco Unity su un server remoto
Martin
2017-01-03 03:30:07 UTC
view on stackexchange narkive permalink

Sto lavorando a un sistema di gioco che utilizza UnityScript e C # sul client e PHP sul server. Un hash MD5 dei dati più un segreto condiviso viene utilizzato per verificare che i dati non siano stati modificati durante il transito. MD5 è abbastanza buono per questo? Quale altro algoritmo hash potrei usare che funzioni in tutte e tre le lingue?

Il problema in modo più dettagliato

Mi sono imbattuto in un codice su un ampiamente utilizzato sito web della comunità sulla popolare piattaforma di sviluppo di giochi Unity e ora sto lavorando per migliorare MySQL, PHP e la sicurezza di quel codice.

Il codice utilizza un valore "chiave segreta" che è condiviso tra il client e il server. Tutti i messaggi dal client includono un hash dei dati (ad es. Nome e punteggio) più la chiave segreta, che il server controlla prima di accettare i dati. Questa è fondamentalmente un'autenticazione con cui i dati passati non sono stati manomessi.

Tuttavia, poiché è MD5, penso che qualcuno che sta ascoltando il traffico di rete possa facilmente elaborare la chiave segreta e quindi pubblicare i dati che desidera vuoi al server.

Quindi le mie domande sono:

  • Questo stato attuale delle cose richiede un miglioramento? O è questo l'uso attuale previsto di MD5 (a partire da gennaio 2017)?
  • Esiste un altro algoritmo di hashing che potrebbe migliorare / autenticare ulteriormente questa attività di comunicazione? Tieni presente che l'algoritmo dovrebbe funzionare in PHP, UnityScript e C #.

Il codice

  • In UnityScript (lato client):

      var hash = Md5.Md5Sum (name + score + secretKey);  
  • In C # (lato client):

      string hash = MD5Test.Md5Sum (name + score + secretKey);  
  • In PHP ( lato server):

      $ secretKey = "mySecretKey"; // Modifica questo valore in modo che corrisponda al valore // memorizzato nel javascript del client sotto $ realHash = md5 ($ _ GET ['name']. $ _GET ['score']. $ SecretKey); if ($ realHash == $ hash) {
    // interact with database}  

Ulteriori criteri

  • Alcuni programmatori Unity utilizzare UnityScript (un linguaggio simile a Python con una sintassi simile a JavaScript sull'API .NET) ma non si può presumere che nessuna libreria sia installata.

  • Gli sviluppatori di giochi sono non programmatori PHP / MySQL così complessi o codice PHP / C # / J di terze parti probabilmente non sarebbe utile.

  • Apparentemente non è saggio usare BCrypt con C #

  • BCrypt necessita di statico salt in questo caso (forse derivato dalla chiave segreta?) ma è destinato a funzionare con un salt casuale.

  • PBKDF2 sembra essere preferito a BCrypt ma può essere molto lento in particolare su dispositivi mobili senza molta memoria.

  • Non ci si può aspettare di avere a che fare con un server protetto (se non altro ...).

  • Non so abbastanza sulla libreria di sicurezza C # per scegliere davvero le migliori opzioni tra quelle elencate.

  • Sebbene il codice delineato abbia semplicemente a che fare con gli aggiornamenti dei punteggi più alti, questo codice è stato in passato - e sarà in futuro - preso e utilizzato per il trasporto di tutti i tipi di dati , pubblico e privato a vari database.

  • Gestire l'interoperabilità degli algoritmi hash tra PHP, UnityScript, C # è un ostacolo più grande di quanto mi aspettassi. Se fosse solo PHP, userei password_hash.

Alcuni pensieri e background a questa domanda:

Ho aggiornato il titolo poiché il titolo modificato sembrava suggerire che non ero sicuro di cambiare MD5, mentre sapere che avrei dovuto cambiare MD5 era uno dei motivi principali per chiedere la domanda qui in primo luogo.

La domanda originale era che volevo aggiornare i terribili suggerimenti sul codice forniti (tra l'altro) qui su come gestire le interazioni tra un gioco su una macchina client e l'archiviazione dei dati su un server remoto . Tieni presente che questo è un suggerimento di codice per i programmatori principianti in Unity e questo sito è [ora] gestito dagli stessi Unity Technologies.
Se guardi, la domanda originale (collegata sopra) utilizzava PHP Mysql_ funzioni (oltre a una forma di DOP non valida piuttosto schifosa). Ho sentito che questo avrebbe tratto beneficio da una riscrittura. Ho visto che il codice originale utilizzava anche una routine md5 per eseguire l'hashing dei dati desiderati. Quando si è trattato della sostituzione di MD5, non mi ero reso conto né della vulnerabilità dei file di progetto compilati né della dimensione / scala del lavoro necessario per rendere questo blocco di codice effettivamente più sicuro (sull'interazione con il server o sul lato client dati). La mia ricerca originale era quella di trovare un sostituto adeguato per l'MD5 che potesse funzionare nei vari linguaggi richiesti (UnityScript, C #, PHP), poiché ero consapevole delle sue carenze. Non mi ero reso conto (a giudicare dai commenti qui) quanto sia noiosamente facile entrare negli exe e acquisire dati codificati.

Questa domanda NON riguarda un gioco che io ' sto facendo, non riguarda il mio progetto e il codice citato che intendo sostituire non è stato scritto da me . Ho letto molti commenti che in qualche modo le persone stanno provando con il messenger, ma questa domanda è nata dal mio desiderio di migliorare una lacuna esistente su un sito wiki didattico. Ho il massimo rispetto per la conoscenza condivisa nel rispondere a questa domanda, ma sono consapevole che negli ultimi 6 mesi esplorando la documentazione di Unity e i siti di apprendimento c'è stato un divario significativo nel proteggere sia le applicazioni locali che il multiplayer o altre interazioni remote.

Vedo molti rispondenti nei commenti che affermano che la risposta data da George è una cattiva risposta, ma risponde alla domanda specifica che ho posto, in quel momento. Grazie.

Nota finale:
Questo post Blob dai commenti di Luke Briggs ha sottolineato quanto sia un processo apertamente facile per manipolare i dati dell'applicazione di gioco Unity locale. Non capivo affatto come i file locali vulnerabili fossero ...

I commenti non sono per discussioni estese;questa conversazione è stata [spostata in chat] (http://chat.stackexchange.com/rooms/51112/discussion-on-question-by-martin-is-md5-a-good-option-for-verifying-game-punteggi).
Ora, smetti di lasciare commenti qui: lasciali nella chat come richiesto.E moe qui verrà cancellato.
Non è molto chiaro dalla domanda, ma _ti_ stai usando Unity?Va notato che Unity ** non supporta JavaScript **.Piuttosto, supporta UnityScript _ (un linguaggio derivato da Python con una sintassi simile a C / JS su .NET) _, che è falsamente pubblicizzato da Unity Technologies come "JavaScript".Questo fa una differenza significativa per come rispondere alla tua domanda perché le librerie standard di JS _non_ sono disponibili in UnityScript.
scrivendo in Unity uso "C #" e conosco i linguaggi "javascript" e "Boo" solo per riferimento, nel contesto di [email protected]
Quello che stai implementando è un (H) MAC, potresti voler dare un'occhiata ad altre informazioni al riguardo -> https://en.wikipedia.org/wiki/Hash-based_message_authentication_code Nel 2011 è stata approvata una RFC 6151 informativa per aggiornare le considerazioni sulla sicurezza in MD5 e HMAC-MD5.Per HMAC-MD5, la RFC riassume che, sebbene la sicurezza della stessa funzione hash MD5 sia gravemente compromessa, gli "attacchi a HMAC-MD5 attualmente noti non sembrano indicare una vulnerabilità pratica se usati come codice di autenticazione del messaggio".
Grazie per il feedback, @GroundZero.Dopo aver pubblicato questa domanda, ho pensato che quello che stavo cercando fosse un HMAC, ma il mio problema era trovare un algoritmo che si adattasse a tutte le varie lingue richieste.Con le risposte a questa domanda trovo che il problema più ampio sia che sia i dati che l'hash possono essere facilmente manipolati dal lato client, quindi l'ambito del problema di sicurezza è molto più ampio di quanto avessi inizialmente previsto (più ampio di quanto qualsiasi HMAC possa risolvere,Credo).
@Martin il problema con qualsiasi cosa lato client è che il client è quasi sempre in grado di manipolare le cose.Se guardi CheatEngine ecc., Spesso lavorano con la manipolazione dei dati nella RAM, ecc., Prima che qualsiasi controllo / crittografia / hash / ... del gioco venga eseguito, bypassando efficacemente l'effetto del tuo HMAC.L'HMAC ti proteggerà dalla manipolazione dei dati mentre sei tra il client e il tuo server, ma ora dalla manipolazione dei dati dal lato del client.Dovresti implementare "controlli di integrità" lato server per confermare che i dati del client rientrino in ciò che ci si aspetta
Quattro risposte:
#1
+202
Polynomial
2017-01-03 04:26:42 UTC
view on stackexchange narkive permalink

Questo approccio è fondamentalmente difettoso. Qualsiasi cosa dal lato client può e sarà manomessa dai giocatori. È lo stesso problema che rende il DRM insostenibile: l'utente possiede la macchina e tutti i dati su di essa, inclusi i tuoi eseguibili, i dati in memoria, ecc. Mantenere gli algoritmi segreti non funziona (vedi Principio di Kerckhoffs ) perché ci vuole solo una piccola quantità di lavoro di reverse engineering per capire cosa sta facendo il tuo codice.

Ad esempio, supponiamo che tu abbia una routine nel tuo client di gioco che pubblica il punteggio di livello fino a il server, utilizzando una crittografia di qualsiasi forma per garantire che non venga manomesso sulla rete. Ci sono molti modi per aggirare questo problema:

  • Usa uno strumento di modifica della memoria come Cheat Engine per cercare il punteggio corrente (mettere in pausa, cercare il punteggio, riattivare, attendere che il punteggio cambia, cerca di nuovo, ripeti fino a trovare l'indirizzo di memoria che contiene il valore) e modificalo. Quando il livello è completo, il valore del punteggio sarà felicemente considerato legittimo dal tuo codice e caricato sul server.
  • Modifica l'eseguibile del gioco su disco in modo che il tuo codice "livello completo" ignori il valore del punteggio reale e ne sceglie uno diverso.
  • Modifica l'eseguibile del gioco su disco in modo che le cose semplici (es. uccidere un mostro) aumentino il tuo punteggio di 1000 volte più del dovuto.
  • Modifica l'eseguibile del gioco su disco in modo che tu non possa mai morire, o avere infiniti potenziamenti, o uccisioni con un solo colpo, o qualsiasi altro numero di cose utili, in modo da poter ottenere facilmente un punteggio molto alto.
  • Esegui uno di questi modifiche in memoria dopo il caricamento del gioco in modo che l'eseguibile originale rimanga intatto (utile nei casi in cui sono presenti fastidiosi controlli di integrità)
  • Esponi semplicemente il codice "abbiamo finito un livello, ora carica il punteggio" esternamente dal processo in modo che possa essere richiamato dal programma di chiunque. Nel codice nativo puoi iniettare un piccolo stub e aggiungere una voce alla tabella di esportazione, o semplicemente copiare il codice direttamente nel tuo eseguibile. In .NET è semplice modificare i flag di visibilità della classe e del metodo e importarli in un nuovo programma. Ora puoi inviare qualsiasi valore di punteggio desideri senza nemmeno avviare il gioco.
  • Effettua il reverse engineering del gioco, procurati la chiave "segreta" e scrivi la tua app per inviare il valore del punteggio al server.

Questa è solo la punta dell'iceberg. Per i giochi più complessi ci sono tutti i tipi di soluzioni alternative per anti-cheat e altri problemi, ma indipendentemente dai trucchi di difesa usati, ci sarà sempre un modo per fare confusione con i valori lato client.

La caratteristica fondamentale di un approccio sicuro è che nulla sul computer del giocatore deve essere considerato attendibile . Quando il codice del tuo server riceve un pacchetto da un giocatore, supponi che il tuo gioco potrebbe non essere nemmeno in esecuzione: potrebbe essere un pezzo di codice totalmente homebrew che mente su tutto.

Proteggere i giochi multiplayer (o qualsiasi tipo di gioco in cui la verifica dello stato del gioco è un requisito) non è facile. Il problema in realtà non è nemmeno di sicurezza, è di usabilità e prestazioni. Il modo più semplice per proteggere una partita multigiocatore è mantenere l'intero stato del gioco sul lato server, eseguire e mantenere lì tutta la logica del gioco e fare in modo che il client non faccia altro che inviare l'input del giocatore al server ("l'utente ha cliccato con il mouse , l'utente tiene premuto il tasto W ") e presenta l'audio e il video al lettore. Il problema con questa operazione è che non è un gioco molto divertente a causa della latenza di rete ed è abbastanza difficile da scalare sul lato server. Invece, devi trovare un equilibrio tra mantenere le cose lato client e lato server. Ad esempio, la logica per "il giocatore ha una chiave per aprire questa porta?" deve essere controllato lato server, ma la logica di quando mostrare l'icona di contesto per "porta aperta" rimane sul lato client. Ancora una volta, cose come la salute e la posizione del nemico devono essere mantenute sul lato server e anche la capacità del giocatore di infliggere danni a quel nemico deve essere verificata (è abbastanza vicino?) Il che significa che l'IA non può essere mantenuta sul lato client, ma cose come la scelta dell'animazione inattiva mostrata dal nemico sarà probabilmente una questione lato client.

Abbiamo alcune domande qui sulla sicurezza del gioco, quindi suggerisco di leggerle:

Consiglio anche queste domande su GameDev SE:

C'è anche un ottimo documento sulla sicurezza multiplayer da BlackHat EU 2013 e un articolo su informazioni non autorevoli Rete P2P, entrambe utili.

Questa è una lettura davvero interessante, non avevo capito quanto facilmente si possa abusare degli indirizzi di memoria per restituire valori modificati.Lo trovo davvero interessante poiché lavorando con PHP ci sono innumerevoli argomenti al giorno sulla sicurezza e la sicurezza generale di Internet, ma l'intero aspetto della sicurezza è qualcosa che da anni di lavoro su Unity ho scoperto essere ... scarso nello sviluppo di giochi, nei tutorial ininsegnamenti, domande e risposte, ecc. Le persone nel complesso non sembrano prenderlo in considerazione, a differenza della tecnologia del web sembra essere un argomento caldo costante (e meglio per questo?).Saluti
È una semplice questione economica.Fino a poco tempo, non c'erano molti soldi da guadagnare barando nei giochi.Oppure, per guardarlo dall'altra parte: non c'erano molti soldi da perdere per essere truffati, quindi perché preoccuparsi di spendere soldi per evitare di barare?Lo stesso non vale per il web, da quando l'eCommerce e poi l'eBanking sono diventati una cosa.
@JörgWMittag Non è nemmeno quello.Le persone sono generalmente più consapevoli di come imbrogliare nei giochi multiplayer in questi giorni e gli strumenti disponibili rendono le cose molto più facili.L'aspetto dell'economia finanziaria conta ancora in alcune aree (in particolare i robot MMO), ma più di ogni altra cosa è stata abbassata la barriera all'ingresso.Oggigiorno puoi creare un trainer di gioco autonomo che esegue le patch del codice e la modifica della memoria senza mai scrivere una singola riga di codice o persino comprendere veramente i concetti alla base di ciò che stai facendo.
Diamine, i giochi includevano codici cheat, quindi lo sfruttamento non era necessario.Fu solo quando le persone gareggiarono su Internet che qualcuno si preoccupò di prevenire i trucchi.
Stavo per inserire un commento nella risposta ma fortunatamente ho controllato altre risposte.QUESTA è la risposta che dovrebbe essere contrassegnata come quella corretta.L'unico modo per assicurarsi che il giocatore non abbia imbrogliato è che il gioco invii la sequenza di input al server e il server la riproduca di nuovo - è fatto in questo modo in DROD, la demo consiste nelle mosse del giocatore, la demo viene inviata al servercome punteggio e solo quando Spider lo riproduce e conferma che lo stato finale è esattamente lo stesso, viene contrassegnato come punteggio valido.
"Quando il codice del tuo server riceve un pacchetto da un giocatore, supponi che il tuo gioco potrebbe non essere nemmeno in esecuzione - potrebbe essere un pezzo di codice totalmente homebrew che mente su tutto." Così vero.Quando avevamo Internet dial-up chiamavamo il numero a mano e facevamo rumori del modem (la versione geek del beatboxing, immagino).Anche se non sapevamo cosa stesse succedendo, in genere aggiungevamo diversi secondi al tempo prima che il lato remoto riattaccasse.Mi sono sempre chiesto se qualcuno potesse trascorrere abbastanza tempo da poter giocare a un gioco in remoto o qualcosa del genere, solo con la propria voce.
Farlo lato server non è in realtà così poco pratico, con alcune modifiche.Piuttosto che mantenere lo stato _interamente_ lato server, mantieni solo alcuni stati rilevanti lato server ed esegui controlli di integrità di base sugli aggiornamenti ("tick") dal client.Ad esempio, mantenere la posizione dei giocatori nel server ed eseguire controlli per assicurarsi che nessun giocatore si sia mosso più velocemente di quanto sia possibile o in modi impossibili, o abbia attraversato confini come muri o scudi.Ciò non impedisce i trucchi banali, ma rompe tutti i trucchi della "salute infinita".
Dopotutto, se il cliente sta segnalando che un giocatore ha gli stessi HP anche dopo che un proiettile ha intersecato la sua hitbox, deve mentire.Non c'è bisogno di fare tutti i calcoli complessi richiesti per vedere esattamente quanto danno è stato fatto (tenendo conto di colpi alla testa, buff al danno, tipo di arma, ecc.), Solo controlli di sanità mentale di base.Questa è la tecnica utilizzata da un certo numero di giochi online per limitare l'abilità di un imbroglione in modo che possa ottenere solo un vantaggio moderato (bot con mira limitata, armi migliori, vedere attraverso i muri) piuttosto che creare una modalità divina (munizioni o salute infinite, uno-colpisci colpi mortali, oggetti infiniti).
#2
+40
Nathaniel J. Smith
2017-01-03 06:56:42 UTC
view on stackexchange narkive permalink

Ci sono tre problemi qui:

  • Quello che stai cercando di fare è fondamentalmente fuorviante in diversi modi, come descritto nella risposta di Polynomial.

  • Se insisti a farlo comunque, non stai nemmeno usando la primitiva giusta! L'autenticazione dei messaggi richiede un MAC, non un hash. È possibile creare un MAC da un hash - questo è ciò che fa HMAC - ma non è così banale come sembra. Quello che il codice che hai incollato sta facendo è provare a costruire ingenuamente un MAC a partire da un hash, e questo tipo di costruzioni ingenue di solito vengono interrotte.

  • Inoltre sì MD5 è un cattivo hash funzione. Ma questa è davvero l'ultima delle tue preoccupazioni ... MD5 non è il punto debole di questo design. Stai chiedendo consigli su come sostituire le sbarre sopra le finestre con una placcatura in acciaio spessa 2 pollici, ma la tua porta d'ingresso è spalancata. Giustificare questo come "sicurezza migliore" non ha senso.

#3
+27
Bryan Field
2017-01-03 04:24:32 UTC
view on stackexchange narkive permalink

Modifica: per chiarire, non posso parlare della sicurezza del tuo approccio, solo della parte hash. Ci sono alcuni commenti forti qui che scoraggiano il tuo approccio. (cioè un buon hash può essere parte di un approccio sicuro o insicuro, proprio come una buona serratura può essere utilizzata su una buona porta / telaio o su una porta / telaio fragile)

In risposta a il tuo TL; DR Posso affermare con certezza che SHA-2 è la funzione hash sostitutiva drop-in consigliata.

Se la lunghezza è un problema, è meglio usare SHA-2 troncato rispetto a MD5.

SHA-2 è disponibile in 4 dimensioni: 224, 256, 384 o 512; con 256 e 512 sono i più comuni.

Tieni presente che questo è un hash per uso generico (veloce) e non è adatto per l'archiviazione delle password, tuttavia è adatto per garantire l'integrità dei dati come TL; DR suggerisce.

BCrypt è un hash password lento e viene utilizzato se è necessaria una sorta di crittografia unidirezionale. (cioè la password non viene mai memorizzata, solo il suo hash, ed è difficile da forzare)

La ringrazio per la risposta.Esaminerò SHA-2, presumo che lo * consiglieresti * come sostituto di Md5?
Sebbene ciò sia vero, vale la pena notare l'avvertenza che nessuna di queste sono opzioni di autenticazione sensate rispetto agli schemi appropriati [SRP] (https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol) e non aiuterà con l'effettivoproblema che OP sta affrontando (utenti che falsificano valori).
La famiglia @Martin SHA2 sarebbe il sostituto ideale per MD5 in quasi tutti i casi in cui ti imbatti in MD5.Ciò non cambia il fatto che il tuo approccio non sia corretto e la modifica dell'hash non migliora la sicurezza, ma MD5 è effettivamente deprecato e gli hash della famiglia SHA2 sono effettivamente la sostituzione consigliata per la maggior parte dei casi d'uso, escluso l'hashing delle password.
Sebbene Polynomial abbia fornito alcuni consigli / critiche molto preziosi e di ampia portata, George ha fornito la risposta che stavo cercando.Grazie a tutti e due.
@Martin In qualità di sviluppatore Unity che vende su Asset Store, spero sinceramente che non utilizzerai questa risposta.Ascolta Polynomial.Molti sviluppatori Unity * capiscono * come funziona l'imbroglio;il tuo schema è ** completamente difettoso ** - insegnarlo / venderlo ad altre persone diffonderà disinformazione.
@Martin come riferimento Ho appena messo insieme due semplici immagini.Vedere [questo] (http://i.imgur.com/fHKuMOE.png) e anche [questo] (http://i.imgur.com/mL48jgO.png).I giochi sono diversi dal web perché è il client che sta cercando di sfruttare il tuo sistema (per imbrogliare).A differenza del Web, dove in genere è una terza parte che cerca di sfruttare il * client * (per rubare da loro).
Sebbene sia d'accordo sul fatto che la risposta polinomiale di seguito sarebbe migliore, probabilmente è meglio usare HMAC (per i dettagli vedere [la sezione sulla sicurezza della pagina di Wikipedia] (https://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Security)).
Sento di dover dare un voto negativo sulla base del fatto che è completamente fuori tema.L'hashing viene eseguito sul lato client, quindi è del tutto banale per chiunque abbia competenze tecniche modificare i valori sottoposti a hashing.La "chiave segreta" non può essere tenuta segreta perché viene data al cliente.L'intera roba di hashing nel post è davvero priva di senso.La risposta di @Polynomial's illustra molto meglio come l'OP si sta avvicinando al problema in un modo molto imperfetto e che l'hashing qui non ha senso.Perché non ha senso, non c'è motivo di elaborazione.
Devo cancellare la mia risposta?lol
Ti consiglio vivamente di contrassegnare un moderatore per eliminarlo.(Non puoi eliminarlo da solo, poiché è accettato.)
@Kat la risposta risponde alla mia specifica esigenza di qualcosa che sostituisce MD5, per l'hashing sul lato client.Da tutti i commenti e le eccellenti risposte su questa domanda, ora mi rendo conto che l'intero approccio avrebbe idealmente bisogno di un ripensamento completo, e l'ho affermato nei commenti più in alto, ma come detto, mentre Polynomial fornisce effettivamente una risposta più completa e più ampia, questaLa risposta di George ha coperto quello che stavo * originariamente * cercando.
@Martin Ho messo insieme [un post sul blog] (https://futrworld.blogspot.co.uk/2017/01/breaking-verified-game-scores-in-unity.html) che mostra quanto sia facile questo tipo dila tecnica è rompere, indipendentemente dalla funzione di hashing utilizzata.Ci sono anche file di progetto in modo che possa essere seguito.
@LukeBriggs è davvero interessante per me, grazie per averlo esaminato.Non mi ero mai reso conto di quanto fosse facile / semplice aprire i dati [di gioco] in questo modo.Ho aggiunto un collegamento a questo blogg al piè di pagina della domanda.
"Se la lunghezza è un problema, è meglio usare uno SHA-2 troncato rispetto a MD5."Non potrei raccomandare di più contro questo approccio.Ciò aumenta le possibilità di collusione poiché più hash potrebbero condividere il contenuto dell'hash troncato.Ad esempio, se si utilizza questo metodo per le password, si passa da una possibile corrispondenza a migliaia di password che potrebbero accedere a quell'account.Lo stesso vale per le risorse.
@baconface, Collision [non è un problema pratico a 128 bit] (https://www.google.com/search?q=how+many+millennia+in+2^128+nanoseconds%3F), anche se è ancora meglio non farlotroncare.
"Se la lunghezza è un problema, è meglio usare uno SHA-2 troncato rispetto a MD5."Sebbene troncare qualsiasi tipo di hash in effetti aumenti il rischio di collisione, credo che ciò a cui questa affermazione stava cercando di ottenere è il fatto che se, per qualche motivo, puoi trasmettere solo 128 bit, un hash SHA-256 troncato a128 bit è ancora molte volte più sicuro di un hash MD5.
Tuttavia, in questa situazione, MD5 è perfettamente a posto.Tutto ciò che Polynomial ha detto di seguito è vero;qualsiasi cosa sul client può essere attaccata.Tuttavia, in questa situazione, la sicurezza per oscurità è davvero la tua unica scelta - almeno rende un po 'più difficile per gli script kiddies manomettere i tuoi punteggi più alti.Sebbene l'MD5 non sia un pollo primaverile, è ancora lungi dall'essere reversibile: avresti comunque bisogno di un attacco di forza bruta.In questo caso, l'implementazione della sicurezza tramite oscurità verrà interrotta molto prima che lo sia la crittografia stessa (MD5).
Sebbene il troncamento di SHA-1 a 128 bit possa aumentare l'oscurità dell'hash nel traffico sniffato, mi spingerei addirittura a dire che faresti meglio a inserire il tuo algoritmo crittografico basato su XOR non così intelligentequesta situazione, nella speranza che renda il codice più difficile da decodificare.(Non perdere tempo su questo: il tuo algoritmo / sarà / verrà crackato alla fine.) Inoltre, direi che il tuo collegamento sull'implementazione di C # bcrypt non verificata non ha importanza qui per gli stessi motivi - non importaquanto è forte e testato il tuo lucchetto quando c'è un buco gigante nel muro proprio accanto alla porta.
@GeorgeBailey Penso che dovresti almeno aggiungere il fatto che l'hashing deve essere fatto lato server, un lato client BCrypt è meno sicuro di un lato server Caesar :)
#4
+11
Luc
2017-01-03 21:16:26 UTC
view on stackexchange narkive permalink

Un mio amico una volta ha creato un gioco in flash (sì, molto tempo fa) e ha usato lo stesso schema: md5 (dati autenticati + chiave segreta) , quindi convalidalo sul server.

Ho eseguito il reverse engineering con qualche strumento e ho trovato il valore segreto che stava usando in circa 30 minuti. Game over.

Ma sì, è la seconda migliore opzione possibile. Indipendentemente dall'utilizzo di sha2 al posto di md5 e indipendentemente dall'utilizzo di hmac invece di un algoritmo di hashing, l'input dell'utente non deve mai essere considerato attendibile. Se gli utenti eseguono il tuo gioco sulla loro macchina (cioè è sotto il loro controllo) e se possono inviare un punteggio alto, saranno sempre in grado di utilizzare strumenti per migliorare i punteggi.

La cosa migliore che puoi fare è caricare un replay (es. pressioni di tasti registrate) e rieseguirlo sul server, quindi convalidare il tempo risultante. È molto lavoro da programmare, richiede più risorse del server e sarà necessario disporre di una fisica deterministica se si utilizzano float ovunque ... ma questa è l'unica cosa migliore di quello che stai facendo e le persone possono ancora scrivere il se vogliono imbrogliare.

Per i giochi a turni che consentono ripetute giocate con lo stesso seme e che sono abbastanza complicati da rendere di per sé un risultato lo sviluppo di un algoritmo per trovare buone soluzioni, penso che si potrebbe rendere discutibile il concetto di "imbroglio".Per i giochi d'azione, tuttavia, non ci sarebbe alcun modo pratico per determinare se qualcuno ha effettivamente giocato al gioco in tempo reale.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...