Krypto für Spielstände

2014-09-17

Es ist immer wieder schön, wenn ich mich mit Crypto beschäftigen kann. Nicht weil ich ein Experte auf diesem Gebiet bin, sondern weil es mich einfach unabhängig von meiner Qualifikation einfach sehr interessiert. Ich bin kein Kryptograph. Bei dieser Gelegenheit ging es darum den Spielstand (Savegame) eines Spiels „sicher“ zu speichern. Dazu gehört als erstes definiert, was man als einen sicheren Spielstand versteht.

  • Geheim – der Inhalt des Spielstandes darf nicht lesbar sein
  • Korrekt – der Inhalt des Spielstandes darf nicht manipulierbar sein

In den den meisten Fällen muss ein Spielstand nicht geheim sein. Es gibt keine Vertraulichkeit darüber, welche Gegenstände im Inventar sind, wie hoch der Highscore ist oder wieviel Lebensenergie der Spieler gerade hat. Darüber hinaus ist ein von Menschen lesbarer Spielstand zu bevorzugen. Es erleichtert bei der Entwicklung einiges wie Fehlersuche oder das Testen. Aber korrekt muss ein Spielstand immer sein! Einfach mal mehr Gold oder Lebensenergie in einen Spielstand zu schreiben ist in aller Regel nicht schwer. In der Regel schadet es keinem, wenn Spieler sich auf diesem Wege das Spiel leichter machen.

Zusammen gefasst wird klar, dass der Spielstand niemals auf Seite des Spielers gespeichert werden sollte, wenn man einen sicheren Spielstand benötigt. Dazu zählen besonders Daten für Mehrspielerspiele oder High Scores für Ranglisten. Daraus folgt, dass „alles in die Cloud“ oder zumindest auf einen Server gespeichert werden muss. Das ist einfach nicht immer praktikabel und Always Online ist für viele Spiele einfach nicht sinnvoll.

Hohe Hürden

Was kann man also tun, wenn man akzeptiert hat, dass man eigentlich nicht gewinnen kann? Man muss es einem mogelnden Spieler so schwer wie möglich zu machen. Der naive Ansatz wäre einfach Binärdaten zu schreiben, da die meisten Menschen diese nicht lesen können. Allerdings hat das schon vor 20 Jahren keine 13-Jährige mit Hexeditor aufgehalten. Zusätzlich verliert man die Vorteile der menschenlesbaren Spielstände.

In meinem konkreten Fall habe ich mich für schnödes XML entschieden. Die De-/Serialisierung ist in aller Regel bereits erschlagen, der Aufwand ist gering. Zum Schutz vor Manipulationen erzeuge ich einen HMAC mit dem der Spielstand signiert wird. Auch das muss nicht selber implementieren, wieder Zeit gespart. Damit wird jeder Manipulationsversuch erkannt. Darüber hinaus kann man die Nachricht mit einer Nutzerkennung oder eine Geräte-ID versehen. Der Spielstand ist so auch an einen Nutzer oder ein Gerät gebunden. Einfaches Tauschen von gültigen Spielständen wird damit unterbunden. Problematisch ist natürlich, dass das Geheimnis zum Signieren im Programm vorliegt. Ein motivierter Angreifer wird diesen finden.

Ob dieses Vorgehen genügt um Ranglisten vor unmöglichen Rekorden schützen wird die Zeit zeigen. Irgendwie freue ich mich auf ein mögliches Wettrüsten. Obwohl in letzter Konsequenz nur das Speichern außerhalb der Reichweite der Spieler erfolgversprechend ist. Dieses Vorgehen hält aber auch ganz andere Fallstricke bereit.