方法来自百度 这里只是当作笔记记录
用于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}");
}
}
}