ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Bundle加密防止AssetStudio获取资源

2021-06-06 18:02:01  阅读:345  来源: 互联网

标签:加密 字节 AssetStudio bundle bundleFile Length Bundle salt


做过Unity bundle资源的同学都知道AssetStudio可以轻易的的破解bundle获取到项目里的原始资源,为了防止自己的项目资源被人使用AssetStudio轻易的获取到,上网研究了下可行的Bundle加密方案,总结有以下两种方式:

1.使用位的异或运算bundle的字节码去加解密,普及下为什么位的异或运算可以实现加解密,因为1 ^ 0 = 1;0 ^ 0 = 0;所以x ^ 0 = x 可实现数据的保持, 位运算中的异或运算满足交换律,所以B ^ A ^ A = B ^ 0 = B,所以在bundle资源打完之后读取bundle的字节数据去异或你的密钥生成加密过后的文件,在加载bundle的时候先读取加密过后的文件的字节数据再去异或一次你的密钥得到原始的bundle字节数据,再使用 AssetBundle.LoadFromMemory(byte[] binary)加载出对应的bundle,此方案是可以实现bundle的加解密,但是上线的项目要考虑性能的问题,该方案在内存性能方面不能满足要求,所以实际线上项目一般不使用该方案

2.还是读取打完bundle的字节数据,然后重新创建对应的文件在头部先写入一段加密的字节数据,再加入bundle的字节数据,在加载bundle的时候使用AssetBundle.LoadFromFile(string path, uint crc, ulong offset) 接口传入你加密的字节数据的长度为offset,也可以加载出对应的bundle,该方案在性能方面基本上没啥另外的消耗,也是本人最终使用的方案。下面贴出对应的加密代码,有兴趣的可以参考借鉴。

[MenuItem("Tools/Encode Bundles", false, 901)]
public static void EncodeBundles()
{
    string bundleDir = Application.dataPath + "/StreamingAssets/xxxx";  //你的bundle文件夹所在路径
    DirectoryInfo dirInfo = new DirectoryInfo(bundleDir);
    string currentDir = dirInfo.Name;
    string encodeDir = Path.Combine(dirInfo.Parent.FullName, currentDir + "_encode");
    if (Directory.Exists(encodeDir))
    {
        Directory.Delete(encodeDir, true);
    }
    Directory.CreateDirectory(encodeDir);

    FileInfo[] abs = dirInfo.GetFiles("*", SearchOption.AllDirectories);
    for (int i = 0; i < abs.Length; i++)
    {
        FileInfo bundleFile = abs[i];
        if (bundleFile.Extension.Equals(".meta") || bundleFile.Extension.Equals(".manifest"))
        {
            continue;
        }

        string newDir = bundleFile.DirectoryName.Replace("\\", "/").Replace(bundleDir, encodeDir);
        if (!Directory.Exists(newDir))
        {
            Directory.CreateDirectory(newDir);
        }

        byte[] salt = "密钥字符串".StringToBytes();  //可通过其它方式生成不同的salt,这里只是简单例子
        byte[] src = File.ReadAllBytes(Path.Combine(bundleFile.DirectoryName, bundleFile.Name));

        byte[] buffer = new byte[src.Length + salt.Length];
        Array.Copy(salt, buffer, salt.Length);
        Array.Copy(src, 0, buffer, salt.Length, src.Length);

        string newFile = Path.Combine(newDir, bundleFile.Name);
        FileStream fs = new FileStream(newFile, FileMode.CreateNew);
        fs.Write(buffer, 0, buffer.Length);
        fs.Close();
    }

    AssetDatabase.Refresh();
}

把bundleDir修改为自己项目的bundle所在路径,处理完会在同级目录下生成对应的同名_encode文件夹,存放加过密的bundle, 其中salt可以替换成另外的生成方式,这里只是简单处理。最后再调用AssetBundle.LoadFromFile(path, 0, salt长度)来加载对应的bundle资源。

注意以下问题:

1.考虑到出包以及热更新,所以不要把原始的bundle目录打在StreamingAssets目录下,而是把加密过后的文件夹放到StreamingAssets目录下打包用,这样别人解压你的包即使拿到bundle文件,也无法轻易用AssetStudio获取到原始资源。

2.如果使用bundle的MD5码记录与对比来实现热更新资源,这时候就应该使用的是加密过后的bundle文件MD5码,而不是原始bundle, 每次热更增量打包后都进行加密处理,保证你的密钥salt不变。

3.试过把salt加在末尾而不是头部是行不通,AssetStudio还是可以解析出原始资源,所以salt还是只能放置头部。

 

 

标签:加密,字节,AssetStudio,bundle,bundleFile,Length,Bundle,salt
来源: https://blog.csdn.net/qq_27831161/article/details/117599465

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有