Unity 数据保存加密

本文介绍了Unity中如何实现数据的保存与加密,通过IOHelper模块详细阐述了数据读写过程,并提供了测试案例以验证其安全性与实用性。
摘要由CSDN通过智能技术生成

IOHelper

using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;


public static class IOHelper
{
    /// <summary>
    /// 判断文件是否存在
    /// </summary>
    /// <param name="fileName">文件路径</param>
    /// <returns></returns>
    public static bool IsFileExists(string fileName)
    {
        return File.Exists(fileName);
    }

    /// <summary>
    /// 判断文件夹是否存在
    /// </summary>
    /// <param name="fileName">文件夹路径</param>
    /// <returns></returns>
    public static bool IsDirectoryExists(string fileName)
    {
        return Directory.Exists(fileName);
    }

    /// <summary>
    /// 创建一个文本文件 
    /// </summary>
    /// <param name="fileName">文件路径</param>
    /// <param name="content">文件内容</param>
    public static void CreateFile(string fileName, string content)
    {
        StreamWriter streamWriter = File.CreateText(fileName);
        streamWriter.Write(content);
        streamWriter.Close();
    }

    /// <summary>
    /// 创建一个文件夹
    /// </summary>
    /// <param name="fileName">文件夹路径</param>
    public static void CreateDirectory(string fileName)
    {
        //文件夹存在则返回
        if (IsDirectoryExists(fileName))
            return;
        Directory.CreateDirectory(fileName);
    }
    /// <summary>
    /// 保存数据写入本地 
    /// </summary>
    /// <param name="fileName">路径xx.sav</param>
    /// <param name="pObject">保存对象 比如类</param>
    public static void SetData(string fileName, object pObject)
    {
        //将对象序列化为字符串
        string toSave = SerializeObject(pObject);
        //对字符串进行加密,32位加密密钥
        //SystemInfo.deviceUniqueIdentifier 返回机器码可以获取android的机器码
        string Key = SystemInfo.deviceUniqueIdentifier.Substring(0, 32);
        //Rijndael 加密  可以换上自己的方法 
        toSave = RijndaelEncrypt(toSave, Key);
        //写入
        StreamWriter streamWriter = File.CreateText(fileName);
        streamWriter.Write(toSave);
        streamWriter.Close();
    }
    /// <summary>
    /// 读取本地数据
    /// </summary>
    /// <param name="fileName">路径xx.sav</param>
    /// <param name="pType">保存对象 比如类</param>
    /// <returns></returns>
    public static object GetData(string fileName, Type pType)
    {
        //打开文本
        StreamReader streamReader = File.OpenText(fileName);
        //读取
        string data = streamReader.ReadToEnd();
        //对数据进行解密,32位解密密钥
        //获取解密密匙
        string Key = SystemInfo.deviceUniqueIdentifier.Substring(0, 32);
       //解密
        data = RijndaelDecrypt(data, Key);
        streamReader.Close();
        //序列化
        return DeserializeObject(data, pType);
    }

    /// <summary>
    /// Rijndael加密算法
    /// </summary>
    /// <param name="pString">待加密的明文</param>
    /// <param name="pKey">密钥,长度可以为:64位(byte[8]),128位(byte[16]),192位(byte[24]),256位(byte[32])</param>
    /// <param name="iv">长度为128(byte[16])</param>
    /// <returns></returns>
    private static string RijndaelEncrypt(string pString, string pKey)
    {
        //密钥
        byte[] keyArray = UTF8Encoding.UTF8.GetBytes(pKey);
        //待加密明文数组
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(pString);
        //Rijndael解密算法
        RijndaelManaged rDel = new RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateEncryptor();
        //返回加密后的密文
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

    /// <summary>
    /// ijndael解密算法
    /// </summary>
    /// <param name="pString">待解密的密文</param>
    /// <param name="pKey">密钥,长度可以为:64位(byte[8]),128位(byte[16]),192位(byte[24]),256位(byte[32])</param>
    /// <param name="iv">iv向量,长度为128(byte[16])</param>
    /// <returns></returns>
    private static String RijndaelDecrypt(string pString, string pKey)
    {
        //解密密钥
        byte[] keyArray = UTF8Encoding.UTF8.GetBytes(pKey);
        //待解密密文数组
        byte[] toEncryptArray = Convert.FromBase64String(pString);

        //Rijndael解密算法
        RijndaelManaged rDel = new RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateDecryptor();
        //返回解密后的明文
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return UTF8Encoding.UTF8.GetString(resultArray);
    }


    /// <summary>
    /// 将一个对象序列化为字符串
    /// </summary>
    /// <returns>The object.</returns>
    /// <param name="pObject">对象</param>
    /// <param name="pType">对象类型</param>
    private static string SerializeObject(object pObject)
    {
        //序列化后的字符串
        string serializedString = string.Empty;
        //使用Json.Net进行序列化      
        serializedString = JsonUtility.ToJson(pObject);    
        return serializedString;
    }

    /// <summary>
    /// 将一个字符串反序列化为对象
    /// </summary>
    /// <returns>The object.</returns>
    /// <param name="pString">字符串</param>
    /// <param name="pType">对象类型</param>
    private static object DeserializeObject(string pString, Type pType)
    {
        //反序列化后的对象
        object deserializedObject = null;
        //使用Json.Net进行反序列化
        deserializedObject = JsonUtility.FromJson(pString, pType);
        return deserializedObject;
    }

}

Test

public class Test: MonoBehaviour {
    public static GameManager instance;
    public SettingsData SettingsData = new SettingsData();

    void Awake()
    {
        instance = this;
        string dirpath = Application.persistentDataPath + "/Save";
        string filename = Application.persistentDataPath + "/Save/xx.sav";
        Debug.Log("存档路径:"+Application.persistentDataPath + "/Save");
        IOHelper.CreateDirectory(dirpath);
        if (IOHelper.IsFileExists(dirpath + "/GameData.sav"))
        {
            SettingsData = (SettingsData)IOHelper.GetData(filename, typeof(SettingsData));
            //读取后操作

        }
        else
        {
             //不存在文件
             //生成新存档
             //后保存

            IOHelper.SetData(filename, SettingsData);

        }


    }   
}
 [Serializable]
    public class SettingsData
    {
        public bool Sound = false;
        public bool Music = false;
        public languages language = languages.Chinese;    
    }
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中进行数据加密可以通过多种方式实现。下面列举了一些常见的方法: 1. 使用对称加密算法:这种方法使用相同的密钥对数据进行加密和解密。Unity中可以使用.NET平台提供的加密库,如AES或DES算法。你可以使用这些算法对敏感数据进行加密,然后再保存文件或传输到网络。 2. 使用非对称加密算法:这种方法使用公钥加密数据,然后使用私钥解密数据Unity中可以使用.NET平台提供的RSA算法。你可以生成一对公钥和私钥,将公钥嵌入到游戏中,用于加密数据,然后使用私钥进行解密。 3. 使用哈希算法:这种方法通常用于验证数据的完整性。你可以使用Unity提供的哈希算法(如MD5或SHA1)对数据进行哈希运算,生成一个固定长度的摘要。在验证数据时,你可以重新计算摘要并与原始摘要进行比较,以确定数据是否被篡改。 4. 使用插件或第三方库:Unity有一个强大的插件生态系统,你可以寻找第三方插件或库来实现更复杂的加密需求。例如,你可以使用开源的加密库(如OpenSSL)来增强Unity加密功能。 无论你选择哪种方法,都需要注意以下几点: - 密钥管理:确保密钥的安全存储和传输,以防止密钥泄露。 - 加密性能:加密算法可能会对性能产生一定影响。在使用加密时,要进行充分的性能测试,以确保不会对游戏的帧率和响应时间产生不良影响。 - 安全性评估:要评估加密方案的安全性,并根据实际需求调整加密的强度。敏感数据的安全性是一个复杂的问题,需要综合考虑多个因素。 请注意,数据加密只是安全性的一部分。在设计游戏时,还需要考虑其他安全措施,如输入验证、防范攻击等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值