In this lesson, you will learn how to implement an AES (Advanced Encryption Standard) layer over your local save files to prevent players from easily editing their game progress using a simple text editor.
Why Encrypt Local Files?
While JsonUtility is excellent for serializing data, storing it as plain text makes it trivial for a player to open the file and change values like playerGold or levelIndex to anything they desire. By encrypting the byte stream before it touches the disk, you move the hurdle from "editing a text file" to "reverse-engineering a cryptographic key."
The Encryption Workflow
To secure your data, you perform a two-step process during saving:
- Serialize: Convert your class data into a JSON string or binary stream.
- Encrypt: Pass that stream through a cryptographic algorithm using a private key (a hardcoded string or byte array).
Here is a simplified example using the System.Security.Cryptography namespace:
using System.IO;
using System.Security.Cryptography;
using System.Text;
public void SaveEncrypted(string data, string key)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key.PadRight(32).Substring(0, 32)); // 256-bit key
aes.GenerateIV(); // Initialization Vector for uniqueness
using (MemoryStream ms = new MemoryStream())
{
ms.Write(aes.IV, 0, aes.IV.Length); // Prepend IV to file
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(data);
}
File.WriteAllBytes(Application.persistentDataPath + "/save.dat", ms.ToArray());
}
}
}
Critical Implementation Notes
- Key Management: Never store your encryption key in a plain text file within your project. While no local client-side key is 100% secure, using obfuscation or deriving the key at runtime makes it significantly harder for unauthorized users to access the data.
- The Initialization Vector (IV): Notice that we save the IV at the start of the file. This ensures that even if two save files contain the exact same data, the encrypted output will look different, preventing "pattern matching" attacks.
- Performance: Encryption adds a small CPU overhead. For most games, this is negligible, but avoid encrypting/decrypting on the main thread if your save data is exceptionally large.
Key Takeaway: Encryption is not a silver bullet, but by applying AES to your serialized data, you effectively deter casual tampering and protect the integrity of your game's progression system.