游戏数据安全性问题的思考

在之前的学习过程中,我了解到了Unity提供的一个存储方式——PlayerPrefs

这种存储方式在不同平台的数据存储位置放在文章末尾。

但是PlayerPrefs的这种存储方式,数据是很容易被找到并且篡改的,目前数据存储最安全的做法依然是

将数据发送到服务器,存储在服务器中。

对于游戏数据发送到服务器,最近也有一些新的想法,以下使用之前开发的一个Html5游戏代码举例:

 1 //博客园目前好像没有TypeScript的编程语言选项,我就选了一个JS
 2 class UserData{
 3     public id: number; // 数据库自增id 唯一id标识
 4     public id_wx: string; // 微信id
 5     public nickname: string; // 用户名
 6     public icon: string; // 用户头像地址
 7     public IP: string; // 用户ip地址
 8     public passLayers: number; // 通过层数
 9     public passLevels: number; // 当前关卡
10     public gameData: GameData;
11 }   
12 
13 class GameData{
14     public noticeNum: number;//提示道具数量
15     public shuffleNum: number;//洗牌道具数量
16     public hpUpNum: number;//加血道具数量
17 }

这样将服务器不需要处理的数据放入一个GameData中,由客户端进行解析和计算,服务端就不需要再增加额外的字段,如果有新的

需要提交的数据,我们只需要在客户端的GameData中添加即可,这些数据在服务端保存,然后原封不动的传回客户端,由客户端解析

可以减小服务器压力。

 

然而,对于很多个人开发者来说,或者对于纯单机游戏来说,不需要服务器的时候,我们也可以使用PlayerPrefs进行数据存储。

如上文的GameData一样,我们可以将数据在客户端进行解析,也就是说,我们使用PlayerPrefs存储一个加密后的数据,然后在

客户端进行读取解析,即可增加一定的数据安全性。

我们可以使用System.Security.Cryptography,或者也可以使用外部库:如 SecurePrefs

示例:

using System.Security.Cryptography;
using System.Text;

public static class SecurePlayerPrefs
{
    private static string encryptionKey = "SecretKey";

    public static void SetEncryptedString(string key, string value)
    {
        string encryptedValue = Encrypt(value, encryptionKey);
        PlayerPrefs.SetString(key, encryptedValue);
    }

    public static string GetEncryptedString(string key)
    {
        string encryptedValue = PlayerPrefs.GetString(key);
        return Decrypt(encryptedValue, encryptionKey);
    }

    private static string Encrypt(string text, string key)
    {
        // 加密逻辑(使用AES等算法)
        return Convert.ToBase64String(Encoding.UTF8.GetBytes(text + key));
    }

    private static string Decrypt(string encryptedText, string key)
    {
        // 解密逻辑
        var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(encryptedText));
        return decoded.Replace(key, "");
    }
}

还可以增加一个校验机制(使用MD5或者SHA256):

string data = "playerScore=100";
string hash = GenerateHash(data); // 使用 SHA256 生成哈希值
PlayerPrefs.SetString("data", data);
PlayerPrefs.SetString("hash", hash);

string savedData = PlayerPrefs.GetString("data");
string savedHash = PlayerPrefs.GetString("hash");

if (GenerateHash(savedData) == savedHash)
{
    Debug.Log("数据未被篡改");
}
else
{
    Debug.Log("数据已被修改!");
}

但是这样做有一个很显著的缺点,就是被逆向破解之后,数据依然可以被篡改。(毕竟数据全部是在客户端进行解析的,但是这种情况,游戏都被逆向了,对于单机游戏来说

数据什么的,反倒是小事情了吧。。。)

 

 

PlayerPrefs在各个平台的存储位置:

1.Windows上的存储位置:

在Windows系统中,PlayerPrefs的数据存储在注册表中。具体路径为:

HKEY_CURRENT_USER/Software/公司名/项目名

公司名和项目名可以在Unity的Edit -> Project Settings -> Player中查看和设置

2.macOS上的存储位置

在macOS系统中,PlayerPrefs的数据存储在以下路径:

~/Library/Preferences/com.公司名.项目名.plist

Unity在编辑器和独立播放器中使用相同的.plist文件

3.Linux上的存储位置

在Linux系统中,PlayerPrefs的数据存储在以下路径:

~/.config/unity3d/公司名/项目名

4.Android上的存储位置

在Android系统中,PlayerPrefs的数据存储在以下路径:

/data/data/pkg-name/shared_prefs/pkg-name.v2.playerprefs.xml

Unity将PlayerPrefs数据存储在设备的SharedPreferences中

5.WebGL上的存储位置

在WebGL平台上,Unity使用浏览器的IndexedDB API存储PlayerPrefs数据

 

posted @ 2024-12-27 10:34  Jet清远  阅读(23)  评论(0编辑  收藏  举报