• Unity AssetBundle 加密


    https://blog.csdn.net/wangjiangrong/article/details/89671861

    前言
    昨天面试,面试官问了些有关AB包相关的知识点,问到了有关AB加密的问题,由于之前没有了解过,而且感觉是一个蛮重要的一个环节。所以今天查了查相关知识,记录一下(要是不对的地方,欢迎大佬们帮忙纠正)

    我们都知道我们的ab包都是放在包体的可读文件夹下,玩家是可以很轻易的取出我们的ab包,若没有做加密处理的话,按照正常的读取ab包的操作,任何人都可以加载出我们ab包的内容,然后并使用,这显然是很不安全的。

    这里我们用一个简单的加密算法,对我们的ab包进行加密。

    思路
    在得到ab包后,我们遍历StreamingAssets目录,获取所有的ab包,然后逐个将ab包转为byte[],然后byte[]中的每一位都和设定好的秘钥key执行异或操作(加密)。最后将新的byte[]重新写入文件中,即加密完成。

    在ab读取的时候,也要从原本的AssetBundle.LoadFromFile()方法转为用AssetBundle.LoadFromMemory()方法,传入的byte[]参数同样是将要读取的ab包转为byte[],然后每一位和秘钥key执行异或操作(解密)。

    注:A 异或 Key = B,B 异或 Key = A。

    代码实现
    本代码是跟着之前打包ab包的工程内加的,首先我们先定义好秘钥和加密解密的方法。

    using System.IO;

    namespace Utility {

    public class FileUtility {

    ......

    const byte m_key = 157;
    /// <summary>
    /// 加密/解密
    /// </summary>
    /// <param name="targetData">文件流</param>
    public static void Encypt(ref byte[] targetData) {
    //加密,与key异或,解密的时候同样如此
    int dataLength = targetData.Length;
    for(int i = 0; i < dataLength; ++i) {
    targetData[i] = (byte)(targetData[i] ^ m_key);
    }
    }
    }
    }
    然后我们在打包完成的时候,读取ab包,并进行加密。(注demo里把ab包全部重新生成了下,然后把StreamAssets下的所有文件进行了加密,实际情况我们只针对差异包加密。同时要避免重复加密的情况)

    namespace AssetBundle {
    public static class BuildAssetBundle {

    ......

    public static IEnumerator EncyptAssetBundle() {
    yield return "开始加密...";
    //遍历streamingAssets目录下所有的ab包,逐个进行加密
    foreach(var f in new DirectoryInfo(AssetBundleUtility.streamingAssetsPath).GetFiles("*.u", SearchOption.AllDirectories)) {
    Byte[] temp = File.ReadAllBytes(f.FullName);
    yield return "加密文件:"+ f.FullName;
    FileUtility.Encypt(ref temp);
    File.WriteAllBytes(f.FullName, temp);
    }
    yield return "加密完成...";
    }

    ......

    }
    }
    然后在打包流程结束后,调用加密方法

    namespace AssetBundle {
    public class BuildAssetBundleWindow : EditorWindow {

    ......

    void Build() {

    ......

    #region 流程

    // 打包
    if (BuildAssetBundleSetting.instance.isBuild) {
    count++;

    IEnumerator buildEtor = BuildAssetBundle.Build();
    while (buildEtor.MoveNext()) {
    yield return buildEtor.Current;
    }
    }

    //加密
    IEnumerator encyptEtor = BuildAssetBundle.EncyptAssetBundle();
    while(encyptEtor.MoveNext()) {
    yield return encyptEtor.Current;
    }

    #endregion

    BuildAssetBundleSetting.instance.Save();

    ......
    }

    ......
    }
    }
    这个时候,打包加密已经完成了,我们打一次ab包,得到结果如下

    在读取ab的时候,若还是使用AssetBundle.LoadFromFile()方法,则会报错如下。这样别的用户就不能随意的读取我们ab包的资源了。

    正确的读法如下,使用LoadFromMemory()方法:

    ab = new AssetBundleItem(path, fileName, isHasDependence);
    byte[] stream = File.ReadAllBytes(ab.pathName);
    //解密
    FileUtility.Encypt(ref stream);
    ab.assetBundle = AssetBundle.LoadFromMemory(stream);
    cacheAssetBundleItemDic.Add(path, ab);
     
    ————————————————
    版权声明:本文为CSDN博主「王王王渣渣」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/wangjiangrong/article/details/89671861

  • 相关阅读:
    Openstack CloudKitty 计量计费命令行操作
    $out表单提交转成数组
    AddWhere
    正则
    全选反选
    showErr()
    模拟登陆
    MYSQL添加权限
    三元相位符
    打开ci 调试
  • 原文地址:https://www.cnblogs.com/nafio/p/11811265.html
Copyright © 2020-2023  润新知