资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 游戏开发 > 其他

利用AssetBundle加解密游戏所需要的资源

其他 更新时间: 发布时间: 计算机考试归档 最新发布

利用AssetBundle加解密游戏所需要的资源

首先需要的是一个编辑器扩展,运用到在编辑器里边创建一个PictureAssetBundle打包,然后将PictureBundle打包在TempStreamingAsset下,然后将TempStreamingAsset下的Assetbundle复制到StreamingAsset下,然后给AssetBundle加解密,等下具体代码附上

public static class ImageEncryption
{
    private static string TEMP_ASSETBUNDLE_PATH = Application.dataPath + "/TempAssetBundle";
    private static string ASSETBUNDLE_NAME = "Picture.assetbundle";
    private static string EncryptKey = "SayYes";

    //将纹理打包成Assetbundle
    [MenuItem("编辑器扩展关于图集/创建PictureBundle")]
    public static void CreateImageAssetBundle()
    {
        List builds = new List();
        AssetBundleBuild build1 = new AssetBundleBuild();

        build1.assetBundleName = ASSETBUNDLE_NAME;
        build1.assetNames = new string[] { "Assets/TestTest/8.png", "Assets/TestTest/9.png","Assets/TestTest/10.png","Assets/TestTest/11.png","Assets/TestTest/12.png","Assets/TestTest/13.png","Assets/TestTest/14.png" };
        builds.Add(build1);


        if (!Directory.Exists(TEMP_ASSETBUNDLE_PATH))
            Directory.CreateDirectory(TEMP_ASSETBUNDLE_PATH);

        if (BuildPipeline.BuildAssetBundles(TEMP_ASSETBUNDLE_PATH, builds.ToArray(), BuildAssetBundleOptions.None, BuildTarget.Android))
        {
            Debug.Log("资源打包成功");
        }

        UnityEditor.AssetDatabase.SaveAssets();
        UnityEditor.AssetDatabase.Refresh();
    }

    [MenuItem("编辑器扩展关于图集/拷贝PictureBundle")]

    //纹理图集加密,并拷贝到StreamingAssets文件夹里

    public static void EncryptExPackImage()
    {

        string assetbundle_file_path = Path.Combine(TEMP_ASSETBUNDLE_PATH, ASSETBUNDLE_NAME.ToLower());
        byte[] bytes = File.ReadAllBytes(assetbundle_file_path);

  
        //字节数组加密,这个可以自己网上搜一下相应的加密算法
        byte[] encryptedBytes = AesMgr.AESEncrypt(bytes,EncryptKey);
        string targetPath = Application.streamingAssetsPath;
        if (!Directory.Exists(targetPath))
            Directory.CreateDirectory(targetPath);

        File.WriteAllBytes(targetPath + "/" + ASSETBUNDLE_NAME.ToLower(), encryptedBytes);

        UnityEditor.AssetDatabase.SaveAssets();
        UnityEditor.AssetDatabase.Refresh();
    }


}

然后在Mono层解密调用,这个可以做在一个场景里边,然后那个场景加载完全部的数据,保存在一个静态类里边,下边简单附上代码,本来那个dictionary应该是用public static 生命才对

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System;

public class LoadAssetBundle : MonoBehaviour
{

    private bool isTextureLoadFinish;
    private Dictionary spritecatch = new Dictionary();
    public Image imageOne, imageTwo;

    public string AssetbundleName = "picture";
    private string EncryptKey = "SayYes";
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(LoadImageByRequestUrl());
        StartCoroutine(ShowImage());
    }

    private IEnumerator LoadImageByRequestUrl()
    {
        string path = " ";


#if UNITY_ANDROID && !UNITY_EDITOR
       path = Application.streamingAssetsPath + "/" + AssetbundleName; 
#else
       path = "file://" + Application.streamingAssetsPath + "/" + AssetbundleName;
#endif
        var uwr = UnityWebRequest.Get(path);

        yield return uwr.SendWebRequest();

        byte[] decryptedBytes = AesMgr.AESDecrypt(uwr.downloadHandler.data,EncryptKey);

        AssetBundle bundleOne = AssetBundle.LoadFromMemory(decryptedBytes);

        Sprite[] Sprites = bundleOne.LoadAllAssets();

        foreach(Sprite sprite in Sprites)
        {
            try
            {
                if (!spritecatch.ContainsKey(sprite.name))
                    spritecatch.Add(sprite.name, sprite);
                else
                    Debug.LogError("List is already Contains" + sprite.name);
            }
            catch(Exception e)
            {
                Debug.LogError("sp.name" + e);
            }
        }
        isTextureLoadFinish = true;
    }

    private IEnumerator ShowImage()
    {
        yield return new WaitUntil(() => { return isTextureLoadFinish; });
        imageOne.sprite = spritecatch["8"];
        imageTwo.sprite = spritecatch["9"];
    }
    // Update is called once per frame
    
}

然后我自己写了一个AesMgr关于加解密资源的

using UnityEngine;
using System.Collections;
using MyGameFrameWork;
using System.IO;
using System.Text;
using System;
using System.Security.Cryptography;

public class AesMgr :BaseManager
{

 

    private static string AESHead = "AESEncrypt";

    /// 
    /// 文件加密,传入文件路径
    /// 
    /// 
    /// 
    /// 


    public static void AESFileEncrypt(string path, string EncrptyKey)
    {
        if (!File.Exists(path))

        {
            Debug.Log("不存在该文件");
            return;
        }
        try
        {
            Debug.Log("执行");
            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                if (fs != null)
                {
                    //读取字节头,判断是否已经加密过了
                    byte[] headBuff = new byte[10];
                    fs.Read(headBuff, 0, headBuff.Length);
                    string headTag = Encoding.UTF8.GetString(headBuff);
                    if (headTag == AESHead)
                    {
#if UNITY_EDITOR
                        Debug.Log(path + "已经加密过了!");
#endif
                        return;
                    }
                    //加密并且写入字节头
                    fs.Seek(0, SeekOrigin.Begin);
                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, Convert.ToInt32(fs.Length));
                    fs.Seek(0, SeekOrigin.Begin);
                    fs.SetLength(0);
                    byte[] headBuffer = Encoding.UTF8.GetBytes(AESHead);
                    fs.Write(headBuffer, 0, headBuffer.Length);
                    byte[] EncBuffer = AESEncrypt(buffer, EncrptyKey);
                    fs.Write(EncBuffer, 0, EncBuffer.Length);
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }
    }
    /// 
    /// 文件解密,传入文件路径(会改动加密文件,不适合运行时)
    /// 
    /// 
    /// 
    public static void AESFileDecrypt(string path, string EncrptyKey)
    {
        if (!File.Exists(path))
        {
            Debug.Log("文件不存在");
            return;
        }
        try
        {
            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                if (fs != null)
                {
                    Debug.Log("开始解密");
                    byte[] headBuff = new byte[10];
                    fs.Read(headBuff, 0, headBuff.Length);
                    string headTag = Encoding.UTF8.GetString(headBuff);
                    if (headTag == AESHead)
                    {
                        byte[] buffer = new byte[fs.Length - headBuff.Length];
                        fs.Read(buffer, 0, Convert.ToInt32(fs.Length - headBuff.Length));
                        fs.Seek(0, SeekOrigin.Begin);
                        fs.SetLength(0);
                        byte[] DecBuffer = AESDecrypt(buffer, EncrptyKey);
                        fs.Write(DecBuffer, 0, DecBuffer.Length);
                        Debug.Log("解密成功");
                    }
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }
    }
    /// 
    /// 文件界面,传入文件路径,返回字节
    /// 
    /// 
    public static byte[] AESFileByteDecrypt(string path, string EncrptyKey)
    {
        if (!File.Exists(path))
        {
            return null;
        }
        byte[] DecBuffer = null;
        try
        {
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (fs != null)
                {
                    byte[] headBuff = new byte[10];
                    fs.Read(headBuff, 0, headBuff.Length);
                    string headTag = Encoding.UTF8.GetString(headBuff);
                    if (headTag == AESHead)
                    {
                        byte[] buffer = new byte[fs.Length - headBuff.Length];
                        fs.Read(buffer, 0, Convert.ToInt32(fs.Length - headBuff.Length));
                        DecBuffer = AESDecrypt(buffer, EncrptyKey);
                    }
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }

        return DecBuffer;
    }
    /// 
    /// AES 加密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
    /// 
    /// 待加密密文
    /// 加密密钥
    public static string AESEncrypt(string EncryptString, string EncryptKey)
    {
        return Convert.ToBase64String(AESEncrypt(Encoding.Default.GetBytes(EncryptString), EncryptKey));
    }
    /// 
    /// AES 加密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
    /// 
    /// 待加密密文
    /// 加密密钥
    public static byte[] AESEncrypt(byte[] EncryptByte, string EncryptKey)
    {
        if (EncryptByte.Length == 0) { throw (new Exception("明文不得为空")); }
        if (string.IsNullOrEmpty(EncryptKey)) { throw (new Exception("密钥不得为空")); }
        byte[] m_strEncrypt;
        byte[] m_btIV = Convert.FromBase64String("Rkb4jvUy/ye7Cd7k89QQgQ==");
        byte[] m_salt = Convert.FromBase64String("gsf4jvkyhye5/d7k8OrLgM==");
        Rijndael m_AESProvider = Rijndael.Create();
        try
        {
            MemoryStream m_stream = new MemoryStream();
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(EncryptKey, m_salt);
            ICryptoTransform transform = m_AESProvider.CreateEncryptor(pdb.GetBytes(32), m_btIV);
            CryptoStream m_csstream = new CryptoStream(m_stream, transform, CryptoStreamMode.Write);
            m_csstream.Write(EncryptByte, 0, EncryptByte.Length);
            m_csstream.FlushFinalBlock();
            m_strEncrypt = m_stream.ToArray();
            m_stream.Close(); m_stream.Dispose();
            m_csstream.Close(); m_csstream.Dispose();
        }
        catch (IOException ex) { throw ex; }
        catch (CryptographicException ex) { throw ex; }
        catch (ArgumentException ex) { throw ex; }
        catch (Exception ex) { throw ex; }
        finally { m_AESProvider.Clear(); }
        return m_strEncrypt;
    }
    /// 
    /// AES 解密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
    /// 
    /// 待解密密文
    /// 解密密钥
    public static string AESDecrypt(string DecryptString, string DecryptKey)
    {
        return Convert.ToBase64String(AESDecrypt(Encoding.Default.GetBytes(DecryptString), DecryptKey));
    }
    /// 
    /// AES 解密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
    /// 
    /// 待解密密文
    /// 解密密钥
    public static byte[] AESDecrypt(byte[] DecryptByte, string DecryptKey)
    {
        if (DecryptByte.Length == 0) { throw (new Exception("密文不得为空")); }
        if (string.IsNullOrEmpty(DecryptKey)) { throw (new Exception("密钥不得为空")); }
        byte[] m_strDecrypt;
        byte[] m_btIV = Convert.FromBase64String("Rkb4jvUy/ye7Cd7k89QQgQ==");
        byte[] m_salt = Convert.FromBase64String("gsf4jvkyhye5/d7k8OrLgM==");
        Rijndael m_AESProvider = Rijndael.Create();
        try
        {
            MemoryStream m_stream = new MemoryStream();
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(DecryptKey, m_salt);
            ICryptoTransform transform = m_AESProvider.CreateDecryptor(pdb.GetBytes(32), m_btIV);
            CryptoStream m_csstream = new CryptoStream(m_stream, transform, CryptoStreamMode.Write);
            m_csstream.Write(DecryptByte, 0, DecryptByte.Length);
            m_csstream.FlushFinalBlock();
            m_strDecrypt = m_stream.ToArray();
            m_stream.Close(); m_stream.Dispose();
            m_csstream.Close(); m_csstream.Dispose();
        }
        catch (IOException ex) { throw ex; }
        catch (CryptographicException ex) { throw ex; }
        catch (ArgumentException ex) { throw ex; }
        catch (Exception ex) { throw ex; }
        finally { m_AESProvider.Clear(); }
        return m_strDecrypt;
    }

}

然后用这个类来加解密AssetBundle,大概就这样了

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/901278.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【利用AssetBundle加解密游戏所需要的资源】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2