开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:1532

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 2367|回复: 9

[海莉zhe] 【知识摘录】Unity3D 使用AES方式加密与解密文件<二>

[复制链接]  [移动端链接]
排名
1529
昨日变化

23

主题

131

帖子

1399

积分

Rank: 9Rank: 9Rank: 9

UID
76890
好友
13
蛮牛币
1921
威望
0
注册时间
2015-3-4
在线时间
477 小时
最后登录
2017-1-18

专栏作家

发表于 2016-9-21 00:35:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 海莉zhe 于 2016-9-21 00:34 编辑

      今天小编为大家介绍如何把保存的文件采用AES 方式加密/解密
   
   
   1.新建一个unity3d项目,新建一个Test.unity场景,场景里面需要有一个摄像机,并且在摄像机上附加一个SaveAESFile.cs组件类,另外还需要在项目新建一个Resources文件夹,这个文件夹为了存放加密的文件。

      1.png


   2.首先需要一个辅助类AES.cs和一个实体类People.cs,然后代码如下:

      ①AES.cs代码如下:


         
[C#] 纯文本查看 复制代码
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Utils
{
    /// <summary>
    /// AES加密解密
    /// </summary>
    public class AES
    {
        #region 加密
        #region 加密字符串
        /// <summary>
        /// AES 加密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
        /// </summary>
        /// <param name="EncryptString">待加密密文</param>
        /// <param name="EncryptKey">加密密钥</param>
        public static string AESEncrypt(string EncryptString, string EncryptKey)
        {
            return Convert.ToBase64String(AESEncrypt(Encoding.Default.GetBytes(EncryptString), EncryptKey));
        }
        #endregion

        #region 加密字节数组
        /// <summary>
        /// AES 加密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
        /// </summary>
        /// <param name="EncryptString">待加密密文</param>
        /// <param name="EncryptKey">加密密钥</param>
        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;
        }
        #endregion
        #endregion

        #region 解密
        #region 解密字符串
        /// <summary>
        /// AES 解密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
        /// </summary>
        /// <param name="DecryptString">待解密密文</param>
        /// <param name="DecryptKey">解密密钥</param>
        public static string AESDecrypt(string DecryptString, string DecryptKey)
        {
            return Convert.ToBase64String(AESDecrypt(Encoding.Default.GetBytes(DecryptString), DecryptKey));
        }
        #endregion

        #region 解密字节数组
        /// <summary>
        /// AES 解密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
        /// </summary>
        /// <param name="DecryptString">待解密密文</param>
        /// <param name="DecryptKey">解密密钥</param>
        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;
        }
        #endregion
        #endregion

    }
}


        ②People.cs 代码如下:

      
[C#] 纯文本查看 复制代码
using System;
namespace Assets
{
    [Serializable]

    public class People
    {
        public People()
        {
        }
        public int ID;
        public string Name;
        public int Age;
    }
}

   

    3.直接是SaveAESFile.cs的核心代码


      
[C#] 纯文本查看 复制代码
using UnityEngine;
using Assets;
using System.Text;
using System;
using System.IO;
using Utils;

public class SaveAESFile : MonoBehaviour
{

    public string FilePath = "";
    private People _people;
    private string info = "";

    /// <summary>
    /// AES 密码保存
    /// </summary>
    private const string _password = "qq123";

    /// <summary>
    /// 一次处理的明文字节数
    /// </summary>
    public static readonly int encryptSize = 10000000;
    /// <summary>
    /// 一次处理的密文字节数
    /// </summary>
    public static readonly int decryptSize = 10000016;


    void Awake()
    {
        FilePath = Application.dataPath + @"/Resources/SaveAESFile.json";
    }

    void OnGUI()
    {
        // 文本显示
        GUI.Label(new Rect(50, 200, 200, 50), info);


        // 第一个文字按钮
        GUI.color = Color.yellow;  //按钮文字颜色  
        GUI.backgroundColor = Color.red; //按钮背景颜色

        if (GUI.Button(new Rect(50, 250, 200, 30), "保存加密文件"))
        {
            info = "保存加密文件!";
            AESSaveFile();
        }

        // 第二个图片按钮
        GUI.color = Color.white;  //按钮文字颜色  
        GUI.backgroundColor = Color.red; //按钮背景颜色

        if (GUI.Button(new Rect(50, 300, 200, 30), "显示解密文件"))
        {
            ShowAESFile();
            info = "显示解密文件!";
            People temp = _people;
            info = "ID:" + _people.ID + "   " + "Name:" + _people.Name + "    " + "Age:" + _people.Age;
        }

    }


    void AESSaveFile()
    {
        AddData();
        byte[] texts = new byte[] { };
        try
        {
            string autoSaveJson = JsonUtility.ToJson(_people);
            //加密
            texts = Utils.AES.AESEncrypt(Encoding.UTF8.GetBytes(autoSaveJson), _password);
        }
        catch (Exception e)
        {
            Debug.LogError("Message:" + e.Message);
        }
        if (File.Exists(FilePath))
        {
            File.Delete(FilePath);
        }
        using (FileStream fs = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write))
        {
            if (fs != null)
            {
                fs.Write(texts, 0, texts.Length);
                fs.Flush();
                fs.Dispose();
            }
        }
    }

    void ShowAESFile()
    {
        try
        {
            string DecrypText = string.Empty;
            using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
            {
                if (fs.Length > 0)
                {
                    int blockCount = ((int)fs.Length - 1) / decryptSize + 1;
                    for (int i = 0; i < blockCount; i++)
                    {
                        int size = decryptSize;
                        if (i == blockCount - 1) size = (int)(fs.Length - i * decryptSize);
                        byte[] bArr = new byte[size];
                        fs.Read(bArr, 0, size);
                        //解密
                        byte[] result = AES.AESDecrypt(bArr, _password);
                        DecrypText += Encoding.UTF8.GetString(result);
                    }
                    fs.Close();
                    fs.Dispose();
                }
            }
            _people = JsonUtility.FromJson<People>(DecrypText);
        }
        catch (Exception e)
        {
            Debug.LogError("Message:" + e.Message);
        }
    }

    void AddData()
    {
        _people = new People();
        _people.ID = 1;
        _people.Name = "小白兔";
        _people.Age = 18;
    }
}



    4.最后便是执行项目看效果啦!
    ①点击解密保存文件,我们会发现在Resources下面会生成一个.json文件,如图下:
   
       2——0.png


       2.png
         
    ②当我们点击按钮解密显示文件时,会发现加密的文件的内容被解密,如图下:
   
       4.png

2——0.png

评分

参与人数 1鲜花 +2 收起 理由
f136338300 + 2

查看全部评分


回复

使用道具 举报

5熟悉之中
651/1000
排名
3528
昨日变化

1

主题

166

帖子

651

积分

Rank: 5Rank: 5

UID
34428
好友
0
蛮牛币
1196
威望
0
注册时间
2014-7-15
在线时间
222 小时
最后登录
2017-1-18
发表于 2016-9-21 09:44:15 | 显示全部楼层
Using 不是会自动调用Dispose 么? 只要继承了IDispose

回复 支持 反对

使用道具 举报

3偶尔光临
245/300
排名
8770
昨日变化

0

主题

42

帖子

245

积分

Rank: 3Rank: 3Rank: 3

UID
31452
好友
0
蛮牛币
195
威望
0
注册时间
2014-6-26
在线时间
131 小时
最后登录
2017-1-17
发表于 2016-9-21 12:48:40 | 显示全部楼层
现在unity3d的破解工具太多了,除了动画数据大部分数据和代码都能还原出来,加密只是戴着面具裸奔

回复 支持 反对

使用道具 举报

5熟悉之中
709/1000
排名
3132
昨日变化

3

主题

224

帖子

709

积分

Rank: 5Rank: 5

UID
68430
好友
0
蛮牛币
3412
威望
0
注册时间
2015-1-14
在线时间
186 小时
最后登录
2017-1-18
发表于 2016-9-21 20:27:54 | 显示全部楼层
我还之前搞了个DES加密呢
[发帖际遇]: 绝世love情缘 乐于助人,奖励 1 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

5熟悉之中
766/1000
排名
4287
昨日变化

6

主题

221

帖子

766

积分

Rank: 5Rank: 5

UID
159103
好友
5
蛮牛币
1875
威望
0
注册时间
2016-8-29
在线时间
281 小时
最后登录
2017-1-18

活力之星迈向小康

发表于 2016-9-22 10:43:27 | 显示全部楼层
感觉好高深啊   先学习一下   肯定能用上

回复 支持 反对

使用道具 举报

5熟悉之中
889/1000
排名
1771
昨日变化

2

主题

75

帖子

889

积分

Rank: 5Rank: 5

UID
104761
好友
0
蛮牛币
3205
威望
0
注册时间
2015-6-1
在线时间
300 小时
最后登录
2017-1-18
QQ
发表于 2016-9-22 16:01:45 | 显示全部楼层
不管如何 先点一下赞,加密的我一直在找,希望可以好好运用

回复 支持 反对

使用道具 举报

5熟悉之中
549/1000
排名
3614
昨日变化

1

主题

216

帖子

549

积分

Rank: 5Rank: 5

UID
4943
好友
0
蛮牛币
751
威望
0
注册时间
2013-10-3
在线时间
72 小时
最后登录
2016-10-17

社区QQ达人

发表于 2016-9-23 00:05:46 | 显示全部楼层
感觉好高深啊   先学习一下

回复 支持 反对

使用道具 举报

5熟悉之中
915/1000
排名
1831
昨日变化

0

主题

145

帖子

915

积分

Rank: 5Rank: 5

UID
31591
好友
0
蛮牛币
204
威望
0
注册时间
2014-6-27
在线时间
270 小时
最后登录
2017-1-18
QQ
发表于 2016-9-26 10:30:34 | 显示全部楼层
感谢楼主分享!现在用上了

回复 支持 反对

使用道具 举报

3偶尔光临
185/300
排名
9961
昨日变化

0

主题

98

帖子

185

积分

Rank: 3Rank: 3Rank: 3

UID
146677
好友
4
蛮牛币
743
威望
0
注册时间
2016-4-25
在线时间
31 小时
最后登录
2016-12-20
QQ
发表于 2016-9-27 20:48:31 | 显示全部楼层
自己能防小白咯,学习了

回复 支持 反对

使用道具 举报

4四处流浪
435/500
排名
5731
昨日变化

1

主题

100

帖子

435

积分

Rank: 4

UID
62741
好友
0
蛮牛币
383
威望
0
注册时间
2014-12-21
在线时间
190 小时
最后登录
2017-1-18
发表于 2016-12-29 16:52:25 | 显示全部楼层
除了json格式,别的也可以加密吗

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表