方法来自百度 这里只是当作笔记记录

用于Unity游戏存档加密 C#语言

using System.IO;
using System.Security.Cryptography;
using UnityEngine;
 
/// <summary>
/// 
/// * Writer:June
/// 
/// * Data:2021.11.9
/// 
/// * Function:Json数据管理器
/// 
/// * Remarks:
/// 
/// </summary>
 
public class JsonDataManager : MonoBehaviour
{
    /// <summary>
    /// 当前创建的密钥
    /// </summary>
    private static byte[] currentKey;
    /// <summary>
    /// 当前创建的初始化向量
    /// </summary>
    private static byte[] currentIV;
    /// <summary>
    /// 保存密钥的文件名
    /// </summary>
    private const string KEYFILENAME = "KeyData.txt";
    /// <summary>
    /// 保存初始化向量的文件名
    /// </summary>
    private const string IVFILENAME = "IVData.txt";
 
    /// <summary>
    /// 保存数据
    /// </summary>
    /// <param name="filePath">文件路径</param>
    /// <param name="obj">需要保存的目标</param>
    public static void SaveData(string filePath, object obj)
    {
        //判断是否存在储存数据的文件,不存在则创建
        DirectoryInfo directoryInfo = new DirectoryInfo(Application.streamingAssetsPath);
        //是否存在文件夹,不存在则创建
        if (!directoryInfo.Exists) Directory.CreateDirectory(directoryInfo.ToString());
        //数据序列化
        string dataStr = JsonUtility.ToJson(obj);
        //实例化算法类
        using (Aes aes = Aes.Create())
        {
            currentKey = aes.Key;
            currentIV = aes.IV;
            //将当前密钥、初始化向量保存在数据文件中
            SaveCurrentKeyAndIv(currentKey, currentIV);
 
            byte[] EncryptionData = AesEncryption(dataStr, aes.Key, aes.IV);
            //将数据写入到文件中
            File.WriteAllBytes(filePath, EncryptionData);
        }
    }
 
    /// <summary>
    /// 加载数据
    /// </summary>
    /// <typeparam name="T">类型</typeparam>
    /// <param name="filePath">文件路径</param>
    /// <returns></returns>
    public static T LoadData<T>(string filePath) where T : class
    {
        //文件是否存在
        if (!File.Exists(filePath))
        {
            Debug.LogError("文件不存在,请检查路径是否有误!");
            return null;
        }
        //读取加密数据
        byte[] readDataBt = File.ReadAllBytes(filePath);
        //文件数据是否为空
        if (readDataBt.Length <= 0)
        {
            Debug.LogError("无数据!");
            return null;
        }
        //如果当前密钥、初始化向量为空,则从配置文件中读取加密时,使用的密钥、初始化向量
        if (currentKey == null || currentKey.Length <= 0 || currentIV == null || currentIV.Length <= 0)
        {
            currentKey = LoadCurrentKey();
            currentIV = LoadCurrentIV();
        }
        if (currentKey.Length <= 0 || currentIV.Length <= 0)
        {
            Debug.LogError("当前创建的密钥或初始化向量为空!");
            return null;
        }
        string decryptData = AesDecrypt(readDataBt, currentKey, currentIV);
        T target = JsonUtility.FromJson<T>(decryptData);
        return target;
    }
 
 
    /// <summary>
    /// 使用对称算法加密(Aes算法)
    /// </summary>
    /// <param name="targetStr">目标内容</param>
    /// <param name="key">对称算法的密钥</param>
    /// <param name="iv">对称算法的初始化向量</param>
    /// <returns></returns>
    private static byte[] AesEncryption(string targetStr, byte[] key, byte[] iv)
    {
        #region 检测参数
        //判断内容是否为空
        if (targetStr == null || targetStr.Length <= 0)
        {
            Debug.LogError("目标内容为空!");
            return null;
        }
        //判断密钥与初始化向量
        if (key == null || key.Length <= 0)
        {
            Debug.LogError("输入密钥为空!");
            return null;
        }
        if (iv == null || iv.Length <= 0)
        {
            Debug.LogError("输入初始化向量为空!");
            return null;
        }
        #endregion
 
        #region 加密
        byte[] encryptionData;          //将数据加密后得到的字节数组
 
        using (Aes aes = Aes.Create())  //新建密钥
        {
            aes.Key = key;
            aes.IV = iv;
            //创建加密程序以执行流转换
            ICryptoTransform cryptoTF = aes.CreateEncryptor(aes.Key, aes.IV);
            //创建用于加密的流
            using (MemoryStream memoryStream =new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTF, CryptoStreamMode.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
                    {
                        streamWriter.Write(targetStr);  //将数据写入到流中
                    }
                    encryptionData = memoryStream.ToArray();
                }
            }
            return encryptionData;
        }
        #endregion
    }
 
 
    /// <summary>
    /// 对称算法解密
    /// </summary>
    /// <param name="targetBtData">需要解密的数据</param>
    /// <param name="key">密钥</param>
    /// <param name="iv">初始化向量</param>
    /// <returns></returns>
    private static string AesDecrypt(byte[] targetBtData, byte[] key, byte[] iv)
    {
        #region 检测参数
        if (targetBtData == null || targetBtData.Length <= 0)
        {
            Debug.LogError("解密数据为空!");
            return null;
        }
        if (key == null || key.Length <= 0)
        {
            Debug.LogError("输入密钥为空!");
            return null;
        }
        if (iv == null || iv.Length <= 0)
        {
            Debug.LogError("输入初始化向量为空!");
            return null;
        }
        #endregion
 
        #region 解密
        string decryptStr;
 
        using (Aes aes = Aes.Create())  //实例化算法类
        {
            aes.Key = key;
            aes.IV = iv;
            //创建解密程序以执行流转换
            ICryptoTransform cryptoTF = aes.CreateDecryptor(aes.Key, aes.IV);
            using (MemoryStream memoryStream = new MemoryStream(targetBtData))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTF, CryptoStreamMode.Read))
                {
                    using (StreamReader streamReader = new StreamReader(cryptoStream))
                    {
                        decryptStr = streamReader.ReadToEnd();
                    }
                }
            }
            return decryptStr;
        }
        #endregion
    }
 
 
    /// <summary>
    /// 保存当前密钥以及初始化向量
    /// </summary>
    /// <param name="keyBt">密钥</param>
    /// <param name="ivBt">初始化向量</param>
    private static void SaveCurrentKeyAndIv(byte[] keyBt, byte[] ivBt)
    {
        //保存key
        string keyDataPath = Path.Combine(Application.streamingAssetsPath, KEYFILENAME);
        File.WriteAllBytes(keyDataPath, keyBt);
        //保存iv
        string ivDataPath = Path.Combine(Application.streamingAssetsPath, IVFILENAME);
        File.WriteAllBytes(ivDataPath, ivBt);
    }
 
 
    /// <summary>
    /// 加载当前密钥
    /// </summary>
    /// <returns></returns>
    private static byte[] LoadCurrentKey()
    {
        //从数据文件中读取
        byte[] keyData = File.ReadAllBytes(Path.Combine(Application.streamingAssetsPath, KEYFILENAME));
        return keyData;
    }
 
    /// <summary>
    /// 加载当前初始化向量
    /// </summary>
    /// <returns></returns>
    private static byte[] LoadCurrentIV()
    {
        byte[] ivData = File.ReadAllBytes(Path.Combine(Application.streamingAssetsPath, IVFILENAME));
        return ivData;
    }
}
 
 
/// <summary>
/// 玩家类
/// </summary>
[System.Serializable]
public class PlayerData
{
    public string playerName;   //玩家名字
    public int attack;          //玩家攻击力
    public int armor;           //护甲
}

使用方法

using System.IO;
using UnityEngine;
 
/// 
/// 
/// * Writer:June
/// 
/// * Data:2021.11.9
/// 
/// * Function:序列化数据测试类
/// 
/// * Remarks:
/// 
/// 
 
 
public class SerializeDataTest : MonoBehaviour
{
    private string filePath;
 
    private void Start() => filePath = Path.Combine(Application.streamingAssetsPath, "Data.txt");
    
 
    private void Update()
    {
        //保存
        if (Input.GetKeyDown(KeyCode.S))
        {
            //实例化玩家
            Player player = new Player()
            {
                playerName = "June",
                attack = 20,
                armor = 50
            };
            SerializeDataManager.SaveData(filePath, player);
        }
        //加载
        if (Input.GetKeyDown(KeyCode.L))
        {
            Player player = SerializeDataManager.LoadData(filePath);
            Debug.Log($"玩家名字:{player.playerName}   攻击力:{player.attack}   护甲:{player.armor}");
        }
    }
}
Last modification:May 1, 2024
If you think my article is useful to you, please feel free to appreciate