shunfy / StreamAssetBundle

Unity AssetBundle 资源加密

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

使用AssetBundle.LoadFromStream和AssetBundle.LoadFromStream对Unity资源进行简单加密

测试的时候发现

    public override int Read(byte[] array, int offset, int count)

AssetBundle在调用Stream.Read读取的时候会多次获取同一块内容 不知道是不是Unity的BUG

using System;
using System.Collections;
using System.IO;
using UnityEngine;

public class EncryptionStream : FileStream
{
    public byte[] EncryKey { get; private set; }

    public static byte[] UInt32ToByte4(uint vl)
    {
        byte[] ret = new byte[4];
        ret[0] = (byte)(vl >> 0);
        ret[1] = (byte)(vl >> 8);
        ret[2] = (byte)(vl >> 16);
        ret[3] = (byte)(vl >> 24);
        return ret;
    }

    public EncryptionStream(string path, FileMode mode, uint encryKey)
        :base(path, mode)
    { EncryKey = UInt32ToByte4(encryKey); }
    public EncryptionStream(string path, FileMode mode, FileAccess access, uint encryKey)
        : base(path, mode, access)
    { EncryKey = UInt32ToByte4(encryKey); }
    public EncryptionStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, uint encryKey)
        : base(path, mode, access, share, bufferSize)
    { EncryKey = UInt32ToByte4(encryKey); }
    public EncryptionStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync, uint encryKey)
        :base(path, mode, access, share, bufferSize, useAsync)
    { EncryKey = UInt32ToByte4(encryKey); }

    public override int Read(byte[] array, int offset, int count)
    {
        int ret = base.Read(array, offset, count);

        for(int i = 0; i < ret; ++i)
        {
            array[i] ^= EncryKey[i % 4];
        }

        return ret;
    }

    public override bool CanSeek => true;
}

public static class StreamEncryption
{
    static uint encryKey = 0x6F7A81F3;

    public static void EcryptAssetBundle(string abPath)
    {
        byte[] EncryKey = EncryptionStream.UInt32ToByte4(encryKey);
        byte[] bytes = File.ReadAllBytes(abPath);
        for (int i = 0; i < bytes.Length; ++i)
        {
            bytes[i] ^= EncryKey[i % 4];
        }
        File.WriteAllBytes(abPath, bytes);
    }

    public static void DecryptAssetBundle(string abPath, string name, Action<UnityEngine.Object> onLoadedCall)
    {
        var fileStream = new EncryptionStream(abPath, FileMode.Open, FileAccess.Read, encryKey);
        var myLoadedAssetBundle = AssetBundle.LoadFromStream(fileStream);
        var obj = myLoadedAssetBundle.LoadAsset<GameObject>(name);
        try
        {
            onLoadedCall(obj);
        }
        catch(System.Exception e)
        {
            Debug.LogError(e.Message);
        }
        myLoadedAssetBundle.Unload(false);
        fileStream.Close();
    }

    public static IEnumerator AsyncLoad(string abPath, string name, Action<UnityEngine.Object> onLoadedCall)
    {
        var fileStream = new EncryptionStream(abPath, FileMode.Open, FileAccess.Read, encryKey);
        var bundleLoadRequest = AssetBundle.LoadFromStreamAsync(fileStream);
        yield return bundleLoadRequest;
        var myLoadedAssetBundle = bundleLoadRequest.assetBundle;
        var assetLoadRequest = myLoadedAssetBundle.LoadAssetAsync(name);
        yield return assetLoadRequest;
        try
        {
            onLoadedCall(assetLoadRequest.asset);
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
        }
        myLoadedAssetBundle.Unload(false);
        fileStream.Close();
    }
}

About

Unity AssetBundle 资源加密


Languages

Language:C# 100.0%