Savegame

From Derail Valley Wiki
Jump to navigation Jump to search

Derail Valley currently only has one savegame.

Saving and Loading

Your game is saved automatically when you exit the game, and it loads automatically when you start the game.

Location

Your savegame is located inside of the Derail Valley folder under DerailValley_Data\SaveGameData and is named "savegame".

The game folder itself can be found by opening the game properties in steam and clicking "Browse local files".

Backup

The game makes regular backups of your game inside of the same folder. If you can't load your game or want to revert your progress to a previous state, you can delete or rename the "savegame" file, and then rename one of the backups to "savegame".

Encryption

Save games are encrypted and stored as Base64. The data is encrypted using the following parameters

Property Value
Type AES-256
Mode CBC
IV Constant 16 bytes: 70 65 6D 67 61 69 6C 39 75 7A 70 67 7A 6C 38 38
KDF PBKDF1
KDF Key WeDidntSecureThisVeryWell!!1
KDF Salt No salt specified
KDF Rounds unspecified (the implementation default is 100)
KDF Hash SHA1
Key size 256 bits (32 bytes)
Block size 128 bits (16 bytes)

Trivia

The IV bytes equal the ASCII string "pemgail9uzpgzl88". This hints at the fact that this key was created using the "cat on keyboard" method.

Because no salt is used and the KDF parameters are constant, the final AES key will always be the same 32 bytes:

00 42 0B 30 C1 C6 B0 51 60 B8 B9 4A C3 25 19 20 64 D1 74 4A 68 92 A0 00 8C C7 2F 57 56 E8 14 C2

This can be represented using the Base64 sequence AEILMMHGsFFguLlKwyUZIGTRdEpokqAAjMcvV1boFMI=

Example Code

The C# code below decrypts the save file. You pass the Base64 string as argument and receive the JSON string as result.

static string FileDecrypt(string SaveData)
{
    var Data = Convert.FromBase64String(SaveData);
    using (var Enc = Aes.Create())
    {
        Enc.Mode = CipherMode.CBC;
        Enc.IV = Encoding.UTF8.GetBytes("pemgail9uzpgzl88");
        Enc.Key = Convert.FromBase64String("AEILMMHGsFFguLlKwyUZIGTRdEpokqAAjMcvV1boFMI=");
        using (var CSDec = Enc.CreateDecryptor())
        {
            using (var MS = new MemoryStream())
            {
                using (var CS = new CryptoStream(MS, CSDec, CryptoStreamMode.Write))
                {
                    CS.Write(Data, 0, Data.Length);
                }
                return Encoding.UTF8.GetString(MS.ToArray());
            }
        }
    }
}

Security

This encryption is good enough for a save file, but under no circumstances should you ever use this to encrypt something of value. The encryption here violates many things you do not want to do when protecting sensitive data:

  • The IV is constant instead of securely randomly generated
  • The key is constant
  • The KDF is misused (no salt)
  • The KDF rounds are way too low
  • The data is not protected against tampering