Savegame
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