SecurePrefs Documentation
Introduction
SecurePrefs is a lightweight utility class for Unity that enhances the security of PlayerPrefs data. It provides a simple way to store and retrieve data with an added layer of obfuscation to make it more difficult for users to tamper with saved values.
SecurePrefs has been designed to improve data security for your Unity projects with minimal implementation overhead. It's perfect for games and applications where you want to protect user progression, settings, or other sensitive data from simple tampering attempts.
Features
- Simple key obfuscation through string reversal
- Value obfuscation through multiplication factor
- Easy-to-use API similar to Unity's PlayerPrefs
- Singleton implementation for easy access
- Minimal performance overhead
Getting Started
Installation
To add SecurePrefs to your Unity project:
- Download the SecurePrefs script from the Advanced Unity HUB package manager
- Import the script into your Unity project's Scripts folder
- Add the SecurePref component to a GameObject in your scene, preferably one that persists throughout your game
It's recommended to attach the SecurePref script to a persistent GameObject that won't be destroyed when loading new scenes. Consider using a dedicated "Managers" GameObject with DontDestroyOnLoad().
Basic Usage
Initialization
Ensure you have a GameObject with the SecurePref component attached. The component initializes itself in Awake().
// In a scene initialization script
public GameObject securePrefsManager;
void Start() {
if (securePrefsManager == null) {
securePrefsManager = new GameObject("SecurePrefsManager");
securePrefsManager.AddComponent<SecurePref>();
DontDestroyOnLoad(securePrefsManager);
}
}
Storing Integer Values
Use SecureSetInt to store integer values safely:
// Store a player's score
SecurePref.Instance.SecureSetInt("playerScore", 1000);
// Store the current level
SecurePref.Instance.SecureSetInt("currentLevel", 5);
This securely stores the values by reversing the key string and multiplying the value by 1000 internally.
Retrieving Integer Values
Use SecureGetInt to retrieve stored integer values:
// Get the player's score
int playerScore = SecurePref.Instance.SecureGetInt("playerScore");
// Get the current level (with a default value of 1 if not found)
int currentLevel = SecurePref.Instance.SecureGetInt("currentLevel");
This retrieves the secured values, automatically reversing the key and dividing the stored value by 1000.
How SecurePrefs Works
SecurePrefs adds two layers of basic security to Unity's PlayerPrefs system:
- Key Obfuscation: When you save data, the key string is reversed. For example, "playerScore" becomes "erocSreyalp".
- Value Obfuscation: Integer values are multiplied by 1000 before storage and divided by 1000 when retrieved.
While this doesn't provide cryptographically strong security, it prevents casual inspection or tampering with the PlayerPrefs data. Users looking at the registry (Windows) or plist files (macOS) won't immediately recognize your application's keys or values.
Complete Example
Here's a complete example showing how to use SecurePrefs in a game context:
using UnityEngine;
public class GameManager : MonoBehaviour
{
// Reference to our player data
private int playerScore;
private int highScore;
private int currentLevel;
void Start()
{
// Load saved data when the game starts
LoadGameData();
}
// Call this when the player completes a level
public void CompleteLevel(int scoreEarned)
{
// Update the player's score
playerScore += scoreEarned;
// Check if this is a new high score
if (playerScore > highScore)
{
highScore = playerScore;
SecurePref.Instance.SecureSetInt("highScore", highScore);
Debug.Log("New high score: " + highScore);
}
// Update the current level
currentLevel++;
// Save the game data
SaveGameData();
Debug.Log("Level completed! New score: " + playerScore);
}
// Save all game data
void SaveGameData()
{
SecurePref.Instance.SecureSetInt("playerScore", playerScore);
SecurePref.Instance.SecureSetInt("currentLevel", currentLevel);
Debug.Log("Game data saved securely!");
}
// Load all game data
void LoadGameData()
{
playerScore = SecurePref.Instance.SecureGetInt("playerScore");
highScore = SecurePref.Instance.SecureGetInt("highScore");
currentLevel = SecurePref.Instance.SecureGetInt("currentLevel");
// If currentLevel is 0 (default), set it to 1 for new players
if (currentLevel == 0)
{
currentLevel = 1;
}
Debug.Log("Game data loaded! Score: " + playerScore + ", Level: " + currentLevel);
}
// Call this when the player wants to reset their progress
public void ResetProgress()
{
playerScore = 0;
currentLevel = 1;
SaveGameData();
Debug.Log("Progress reset!");
}
}
Using the String Reverse Utility
SecurePrefs includes a string reversal utility that you can use directly if needed:
// Using the string reverse utility
string originalString = "Hello World";
string reversedString = SecurePref.Reverse(originalString);
Debug.Log(reversedString); // Outputs: "dlroW olleH"
// Reverse it back to the original
string backToOriginal = SecurePref.Reverse(reversedString);
Debug.Log(backToOriginal); // Outputs: "Hello World"
Tips and Best Practices
- Always use consistent key names across your project to avoid confusion
- Consider creating a dedicated class to manage all your SecurePrefs keys and operations
- Remember that SecurePrefs values are divided by 1000, so they have limited precision (only three decimal places)
- For very sensitive data, consider implementing additional security measures
- Be aware that determined users can still modify PlayerPrefs data, so don't rely on it for critical security
SecurePrefs offers basic obfuscation, not true encryption. For highly sensitive data or anti-cheat systems, consider using more robust security measures or a dedicated secure storage solution.
Current Limitations
The current implementation of SecurePrefs has some limitations:
- Only supports integer values (no float, string, or boolean support yet)
- Uses a fixed multiplication factor of 1000, which limits precision
- The key reversal scheme is relatively simple and could be detected
Future versions may add support for additional data types and more sophisticated security measures.