源码-加密解密机制
篇章 :06-源码深度-文件系统与下载模块
阅读时间 :约 20 分钟
前置知识:了解 IFileSystem
一、引言
本章将深入解析 YooAsset 加密解密机制的源码实现。加密解密是 YooAsset 资源保护的重要机制,通过加密可以保护游戏资源不被非法获取和修改。深入理解加密解密机制有助于开发者保护游戏资产。
YooAsset 提供了 AES 和 XOR 两种加密方式,支持整体 Bundle 加密和单个资源加密。本章将从源码层面深入解析加密解密机制的实现。
二、IDecryptionServices 接口
2.1 IDecryptionServices 概述
IDecryptionServices 是 YooAsset 加密解密服务的接口:
作用:
- 定义加密解密的统一接口
- 支持开发者自定义加密方式
- 与 Collector 集成配置加密选项
2.2 接口定义
public interface IDecryptionServices
{
/// <summary>
/// 加密方法
/// </summary>
/// <param name="fileData">文件数据</param>
/// <returns>加密后的数据</returns>
byte[] Encrypt(byte[] fileData);
/// <summary>
/// 解密方法
/// </summary>
/// <param name="fileData">加密的文件数据</param>
/// <returns>解密后的数据</returns>
byte[] Decrypt(byte[] fileData);
}
Encrypt 方法详解:
Encrypt 方法用于加密文件数据,接收原始数据返回加密数据。
Decrypt 方法详解:
Decrypt 方法用于解密文件数据,接收加密数据返回原始数据。
2.3 接口实现
public class DecryptionServices : IDecryptionServices
{
private byte[] _encryptionKey;
public DecryptionServices(byte[] encryptionKey)
{
_encryptionKey = encryptionKey;
}
public byte[] Encrypt(byte[] fileData)
{
// 使用 AES 加密
return AESHelper.Encrypt(fileData, _encryptionKey);
}
public byte[] Decrypt(byte[] fileData)
{
// 使用 AES 解密
return AESHelper.Decrypt(fileData, _encryptionKey);
}
}
构造函数详解:
通过构造函数注入加密密钥。
方法实现详解:
实现加密和解密方法,调用 AES 加密库。
2.4 接入方式
var package = YooAssets.CreatePackage("DefaultPackage");
var initParameters = new HostPlayModeParameters();
initParameters.AssetBundleDecryptionServices = new DecryptionServices(encryptionKey);
YooAssets.InitPackage(package);
接入方式详解:
通过初始化参数注入解密服务。
三、AES 加密
3.1 AES 概述
AES(Advanced Encryption Standard)是高级加密标准:
特点:
- 对称加密算法
- 安全性高
- 性能较好
- 标准化程度高
YooAsset 中的应用:
- Bundle 整体加密
- 单个资源加密
3.2 AES 实现
public class AESHelper
{
public static byte[] Encrypt(byte[] data, byte[] key)
{
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// 生成 IV
aes.GenerateIV();
byte[] iv = aes.IV;
// 创建加密器
using (ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, iv))
using (MemoryStream ms = new MemoryStream())
{
// 写入 IV
ms.Write(iv, 0, iv.Length);
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
}
return ms.ToArray();
}
}
}
public static byte[] Decrypt(byte[] data, byte[] key)
{
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// 读取 IV
byte[] iv = new byte[16];
Array.Copy(data, 0, iv, 0, 16);
aes.IV = iv;
// 创建解密器
using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
using (MemoryStream ms = new MemoryStream(data, 16, data.Length - 16))
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
using (MemoryStream output = new MemoryStream())
{
cs.CopyTo(output);
return output.ToArray();
}
}
}
}
AES.Create 详解:
使用 .NET 提供的 Aes 类创建 AES 实例。
CBC 模式详解:
CBC(Cipher Block Chaining)模式是常用的分组加密模式。
PKCS7 填充详解:
PKCS7 是常用的填充方式。
IV(初始化向量)详解:
IV 用于增加加密的随机性,每次加密生成新的 IV。
3.3 AES 性能优化
public class AESHelper
{
public static byte[] EncryptOptimized(byte[] data, byte[] key)
{
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.GenerateIV();
// 使用 AES.CreateEncryptor 预创建加密器
using (ICryptoTransform encryptor = aes.CreateEncryptor())
{
return encryptor.TransformFinalBlock(data, 0, data.Length);
}
}
}
}
预创建加密器详解:
预创建加密器可以减少加密过程中的开销。
TransformFinalBlock 详解:
TransformFinalBlock 一次性完成加密,避免多次写入。
四、XOR 加密
4.1 XOR 概述
XOR(异或)是一种简单的加密方式:
特点:
- 简单、快速
- 安全性较低
- 适合临时加密
- 适合小文件加密
YooAsset 中的应用:
- Bundle 整体加密
- 单个文件加密
4.2 XOR 实现
public class XORHelper
{
public static byte[] Encrypt(byte[] data, byte[] key)
{
byte[] result = new byte[data.Length];
for (int i = 0; i < data.Length; i++)
{
result[i] = (byte)(data[i] ^ key[i % key.Length]);
}
return result;
}
public static byte[] Decrypt(byte[] data, byte[] key)
{
return Encrypt(data, key); // XOR 解密与加密相同
}
}
XOR 原理详解:
XOR 加密通过将数据与密钥进行异或运算。
XOR 解密详解:
XOR 加密是可逆的,解密与加密相同。
4.3 XOR 性能优化
public class XORHelper
{
public static unsafe byte[] EncryptOptimized(byte[] data, byte[] key)
{
byte[] result = new byte[data.Length];
int keyLength = key.Length;
fixed (byte* pData = data, pKey = key, pResult = result)
{
for (int i = 0; i < data.Length; i++)
{
pResult[i] = (byte)(pData[i] ^ pKey[i % keyLength]);
}
}
return result;
}
}
unsafe 代码优化详解:
使用 unsafe 代码和指针可以提高性能。
适用场景详解:
unsafe 代码适合性能要求高的场景,但需要注意平台兼容性。
4.4 XOR 安全性
XOR 安全性较低:
- 容易被破解
- 不适合保护重要资源
- 适合临时加密
增强安全性的方法:
- 使用更长的密钥
- 多重 XOR
- 结合其他加密方式
五、加密策略
5.1 整体加密 vs 单个资源加密
整体加密详解:
对整个 Bundle 文件加密,加密粒度大,性能好但灵活性低。
单个资源加密详解:
对 Bundle 中的每个资源单独加密,加密粒度小,灵活性高但性能差。
YooAsset 推荐:
默认使用整体 Bundle 加密,在安全和性能之间取得平衡。
5.2 加密范围
// 1. 所有 Bundle 都加密
parameters.EnableEncryption = true;
// 2. 指定 Bundle 加密
[AssetBundleEncryptRule("critical_bundle")]
public bool ShouldEncrypt(string bundleName) { return true; }
全量加密详解:
所有 Bundle 都加密,安全性最高,但性能开销最大。
选择性加密详解:
只加密关键 Bundle,平衡安全性和性能。
5.3 加密密钥管理
public class KeyManager
{
private byte[] _key;
public KeyManager()
{
// 从安全存储加载密钥
_key = LoadKeyFromSecureStorage();
}
public byte[] GetKey()
{
return _key;
}
private byte[] LoadKeyFromSecureStorage()
{
// 从安全存储加载密钥
// 例如:Keystore、Keychain 等
}
}
密钥管理的重要性:
密钥管理是加密安全的关键,密钥不能明文存储在代码中。
密钥管理方式:
- iOS:Keychain
- Android:Keystore
- 通用:加密配置文件
5.4 加密与性能
加密对性能的影响:
- 增加打包时间
- 增加运行时解密开销
- 增加包体大小
性能优化:
- 只加密关键资源
- 使用硬件加速(AES-NI)
- 缓存解密结果
六、加密实战
6.1 完整加密实现示例
public class BundleEncryptionExample
{
public static void SetupEncryption()
{
// 1. 创建 Package
var package = YooAssets.CreatePackage("GamePackage");
// 2. 配置加密服务
var initParameters = new HostPlayModeParameters();
byte[] encryptionKey = new byte[32]; // 256 位密钥
new System.Random().NextBytes(encryptionKey);
initParameters.AssetBundleDecryptionServices = new DecryptionServices(encryptionKey);
// 3. 初始化 Package
YooAssets.InitPackage(package);
}
}
public class DecryptionServices : IDecryptionServices
{
private byte[] _key;
public DecryptionServices(byte[] key)
{
_key = key;
}
public byte[] Encrypt(byte[] fileData)
{
return AESHelper.Encrypt(fileData, _key);
}
public byte[] Decrypt(byte[] fileData)
{
return AESHelper.Decrypt(fileData, _key);
}
}
完整流程详解:
- 创建 Package
- 配置加密服务
- 初始化 Package
密钥生成详解:
使用随机数生成 32 字节(256 位)的密钥。
6.2 加密配置
[CreateAssetMenu(fileName = "PackageConfig", menuName = "YooAsset/Package Config")]
public class PackageConfig : ScriptableObject
{
public bool EnableEncryption;
public string EncryptionKey;
public EEncryptionType EncryptionType = EEncryptionType.AES;
}
配置参数详解:
- EnableEncryption:是否启用加密
- EncryptionKey:加密密钥
- EncryptionType:加密类型
6.3 加密测试
public class EncryptionTest
{
public static void TestEncryption()
{
byte[] original = System.Text.Encoding.UTF8.GetBytes("Hello, YooAsset!");
byte[] key = new byte[32];
new System.Random().NextBytes(key);
// 加密
byte[] encrypted = AESHelper.Encrypt(original, key);
// 解密
byte[] decrypted = AESHelper.Decrypt(encrypted, key);
// 验证
Debug.Assert(System.Text.Encoding.UTF8.GetString(decrypted) == "Hello, YooAsset!");
}
}
测试目的详解:
验证加密和解密的正确性。
测试步骤详解:
- 准备原始数据
- 生成密钥
- 加密
- 解密
- 验证
七、总结
本章深入解析了 YooAsset 加密解密机制的源码实现,包括:
- IDecryptionServices 接口:接口定义、实现、接入方式
- AES 加密:AES 概述、实现、性能优化
- XOR 加密:XOR 概述、实现、性能优化、安全性
- 加密策略:整体加密 vs 单个资源加密、加密范围、密钥管理
- 加密实战:完整实现示例、配置、测试
通过深入理解加密解密机制,开发者可以保护游戏资源不被非法获取和修改。
下一篇 :YooAsset 快速入门