2016-11-25 155 views
0

我在Unity中整合了this module。 我希望能够解密用AES加密的文件。Unity AES加密器

这里是我的代码的一部分:

using UnityEngine; 
using System.Collections; 
using System.Security.Cryptography; 

public class LoadEncryptBundle : MonoBehaviour { 

// Use this for initialization 
void Start() { 
    StartCoroutine(Load()); 
} 

// Update is called once per frame 
void Update() { 

} 

// string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d"; 
string url = "file:///G:/UnityDecryptBundle/Bundles/3341_windows.unity3d.aes"; 
IEnumerator Load() 
{ 
    // Start a download of the encrypted assetbundle 
    WWW www = new WWW(url); 

    // Wait for download to complete 
    yield return www; 
    System.Diagnostics.Debug.WriteLine("File downloaded"); 
    // Get the byte data 
    byte[] encryptedData = www.bytes; 

    // Decrypt the AssetBundle data 
    byte[] decryptedData = AvoEx.AesEncryptor.Decrypt(encryptedData); 

    // Create an AssetBundle from the bytes array 

    AssetBundleCreateRequest acr = AssetBundle.LoadFromMemoryAsync(decryptedData); 
    yield return acr; 

    AssetBundle bundle = acr.assetBundle; 

    // Load the object asynchronously 
    AssetBundleRequest request = bundle.LoadAllAssetsAsync<GameObject>(); 

    // Wait for completion 
    yield return request; 


    // Get the reference to the loaded object 
    GameObject[] objs = request.allAssets as GameObject[]; 
    foreach (GameObject obj in request.allAssets) 
    { 
     Instantiate(obj); 
    } 
    // Unload the AssetBundles compressed contents to conserve memory 
    bundle.Unload(false); 

    // Frees the memory from the web stream 
    www.Dispose(); 
} 

} 

这里我下载的加密文件,并尝试使用另一个文件中设置的关键,而params对其进行解密:

using UnityEngine; 
using System; 
using System.Text; 
using System.Security.Cryptography; 
using System.Linq; 

/* See the "http://avoex.com/avoex/default-license/" for the full license governing this code. */ 

namespace AvoEx 
{ 
    // based on http://stackoverflow.com/questions/165808/simple-two-way-encryption-for-c-sharp 
    public static class AesEncryptor 
    { 
     // only the 128, 192, and 256-bit key sizes are specified in the AES standard. https://en.wikipedia.org/wiki/Advanced_Encryption_Standard 
     const int keySize = 16; // keySize must be 16, 24 or 32 bytes. 
     const string keyString = "coincoincoincoin"; // EDIT 'keyString' BEFORE RELEASE. keyString must be longer than keySize. 
     // DO NOT EDIT 'keySize, keyString' AFTER RELEASE YOUR PROJECT. 
     // if you change keyString, you can not decrypt saved data encrypted by old keyString. 

     // The size of the IV property must be the same as the BlockSize property divided by 8. 
     // https://msdn.microsoft.com/ko-kr/library/system.security.cryptography.symmetricalgorithm.iv(v=vs.110).aspx 
     const int IvLength = 16; 
     static readonly UTF8Encoding encoder; 
     static readonly AesManaged aes; 

     static AesEncryptor() 
     { 

      encoder = new UTF8Encoding(); 
      aes = new AesManaged { Key = encoder.GetBytes(keyString).Take(keySize).ToArray() }; 
      aes.BlockSize = IvLength * 8; // only the 128-bit block size is specified in the AES standard. 
     } 

     public static byte[] GenerateIV() 
     { 
      aes.GenerateIV(); 
      return aes.IV; 
     } 

     #region PREPEND_VECTOR 
     /// <summary> 
     /// encrypt bytes with random vector. prepend vector to result. 
     /// </summary> 
     public static byte[] Encrypt(byte[] buffer) 
     { 
      aes.GenerateIV(); 
      using (ICryptoTransform encryptor = aes.CreateEncryptor()) 
      { 
       byte[] inputBuffer = encryptor.TransformFinalBlock(buffer, 0, buffer.Length); 
       return aes.IV.Concat(inputBuffer).ToArray(); 
      } 
     } 

     /// <summary> 
     /// decrypt bytes, encrypted by Encrypt(byte[]). 
     /// </summary> 
     public static byte[] Decrypt(byte[] buffer) 
     { 
      byte[] iv = buffer.Take(IvLength).ToArray(); 
      using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, iv)) 
      { 

       return decryptor.TransformFinalBlock(buffer, IvLength, buffer.Length - IvLength); 
      } 
     } 
     #endregion PREPEND_VECTOR 

     #region CUSTOM_KEY 
     /// <summary> 
     /// not prepend vector to result. you must use DecryptIV(byte[], byte[]) to decrypt. 
     /// </summary> 
     public static byte[] EncryptIV(byte[] buffer, byte[] IV) 
     { 
      return EncryptKeyIV(buffer, aes.Key, IV); 
     } 

     /// <summary> 
     /// decrypt bytes, encrypted by EncryptIV(byte[], byte[]). 
     /// </summary> 
     public static byte[] DecryptIV(byte[] buffer, byte[] IV) 
     { 
      return DecryptKeyIV(buffer, aes.Key, IV); 
     } 

     public static byte[] EncryptKeyIV(byte[] buffer, byte[] key, byte[] IV) 
     { 
      using (ICryptoTransform encryptor = aes.CreateEncryptor(key, IV)) 
      { 
       return encryptor.TransformFinalBlock(buffer, 0, buffer.Length); 
      } 
     } 

     public static byte[] DecryptKeyIV(byte[] buffer, byte[] key, byte[] IV) 
     { 
      using (ICryptoTransform decryptor = aes.CreateDecryptor(key, IV)) 
      { 
       return decryptor.TransformFinalBlock(buffer, 0, buffer.Length); 
      } 
     } 
     #endregion CUSTOM_KEY 

     #region ENCRYPT_TO_STRING 
     // string 
     /// <summary> 
     /// encrypt string with random vector. prepend vector to result. 
     /// </summary> 
     public static string Encrypt(string unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(encoder.GetBytes(unencrypted))); 
     } 

     /// <summary> 
     /// decrypt string, encrypted by Encrypt(string). 
     /// </summary> 
     [Obsolete("Decrypt(string) has been made obsolete. Please use the DecryptString(string).")] 
     public static string Decrypt(string encrypted) 
     { 
      return DecryptString(encrypted); 
     } 
     public static string DecryptString(string encrypted) 
     { 
      return DecryptString(Convert.FromBase64String(encrypted)); 
     } 
     public static string DecryptString(byte[] encrypted) 
     { 
      byte[] bytesDecrypted = Decrypt(encrypted); 
      return encoder.GetString(bytesDecrypted, 0, bytesDecrypted.Length); 
     } 

     /// <summary> 
     /// not prepend vector to result. you must use DecryptIV(string, byte[]) to decrypt. 
     /// </summary> 
     public static string EncryptIV(string unencrypted, byte[] vector) 
     { 
      return Convert.ToBase64String(EncryptIV(encoder.GetBytes(unencrypted), vector)); 
     } 

     /// <summary> 
     /// decrypt string, encrypted by EncryptIV(string, byte[]). 
     /// </summary> 
     public static string DecryptIV(string encrypted, byte[] vector) 
     { 
      byte[] bytesDecrypted = DecryptIV(Convert.FromBase64String(encrypted), vector); 
      return encoder.GetString(bytesDecrypted, 0, bytesDecrypted.Length); 
     } 

     // bool 
     public static string Encrypt(bool unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static bool DecryptBool(string encrypted) 
     { 
      return DecryptBool(Convert.FromBase64String(encrypted)); 
     } 
     public static bool DecryptBool(byte[] encrypted) 
     { 
      return BitConverter.ToBoolean(Decrypt(encrypted), 0); 
     } 

     // char 
     public static string Encrypt(char unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static char DecryptChar(string encrypted) 
     { 
      return DecryptChar(Convert.FromBase64String(encrypted)); 
     } 
     public static char DecryptChar(byte[] encrypted) 
     { 
      return BitConverter.ToChar(Decrypt(encrypted), 0); 
     } 

     // double 
     public static string Encrypt(double unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static double DecryptDouble(string encrypted) 
     { 
      return DecryptDouble(Convert.FromBase64String(encrypted)); 
     } 
     public static double DecryptDouble(byte[] encrypted) 
     { 
      return BitConverter.ToDouble(Decrypt(encrypted), 0); 
     } 

     // float 
     public static string Encrypt(float unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static float DecryptFloat(string encrypted) 
     { 
      return DecryptFloat(Convert.FromBase64String(encrypted)); 
     } 
     public static float DecryptFloat(byte[] encrypted) 
     { 
      return BitConverter.ToSingle(Decrypt(encrypted), 0); 
     } 

     // int 
     public static string Encrypt(int unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 
     public static int DecryptInt(string encrypted) 
     { 
      return DecryptInt(Convert.FromBase64String(encrypted)); 
     } 
     public static int DecryptInt(byte[] encrypted) 
     { 
      return BitConverter.ToInt32(Decrypt(encrypted), 0); 
     } 

     // long 
     public static string Encrypt(long unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static long DecryptLong(string encrypted) 
     { 
      return DecryptLong(Convert.FromBase64String(encrypted)); 
     } 
     public static long DecryptLong(byte[] encrypted) 
     { 
      return BitConverter.ToInt64(Decrypt(encrypted), 0); 
     } 

     // short 
     public static string Encrypt(short unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static short DecryptShort(string encrypted) 
     { 
      return DecryptShort(Convert.FromBase64String(encrypted)); 
     } 
     public static short DecryptShort(byte[] encrypted) 
     { 
      return BitConverter.ToInt16(Decrypt(encrypted), 0); 
     } 

     // uint 
     public static string Encrypt(uint unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static uint DecryptUInt(string encrypted) 
     { 
      return DecryptUInt(Convert.FromBase64String(encrypted)); 
     } 
     public static uint DecryptUInt(byte[] encrypted) 
     { 
      return BitConverter.ToUInt32(Decrypt(encrypted), 0); 
     } 

     // ulong 
     public static string Encrypt(ulong unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static ulong DecryptULong(string encrypted) 
     { 
      return DecryptULong(Convert.FromBase64String(encrypted)); 
     } 
     public static ulong DecryptULong(byte[] encrypted) 
     { 
      return BitConverter.ToUInt64(Decrypt(encrypted), 0); 
     } 

     // ushort 
     public static string Encrypt(ushort unencrypted) 
     { 
      return Convert.ToBase64String(Encrypt(BitConverter.GetBytes(unencrypted))); 
     } 

     public static ushort DecryptUShort(string encrypted) 
     { 
      return DecryptUShort(Convert.FromBase64String(encrypted)); 
     } 
     public static ushort DecryptUShort(byte[] encrypted) 
     { 
      return BitConverter.ToUInt16(Decrypt(encrypted), 0); 
     } 
     #endregion ENCRYPT_TO_STRING 
    } 
} 

主要是好的,但我得到这个错误,当我运行它:

CryptographicException: Invalid input block size. 

Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) 

Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) 

AvoEx.AesEncryptor.Decrypt (System.Byte[] buffer) (at Assets/AvoEx/AesEncryptor/AesEncryptor.cs:63) 

LoadEncryptBundle+<Load>c__Iterator1.MoveNext() (at Assets/LoadEncryptBundle.cs:31) 

UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17) 

我不知道如何调试这一点,

预先感谢您的回答,

快乐黑色星期五/感恩

回答

0

我不熟悉具体的图书馆,但它会从documentation linked看来,这的确是预期的块大小bits而不是bytes。您可以使用LegalBlockSizes来验证预期的块大小。

您知道这里使用的cipher block mode of operation吗?它很可能默认为CBC,但这并不表示任何地方。 CBC要求将密文填充到块边界。您是否验证了密文正确填充,并且是n + 1块(即(n + 1) * 8位)长?第一个16字节是用于加密该消息的IV字节,其余字节(必须可被16整除)是实际的密文。

您能否使用AES的另一个实现成功解密此内容?有多种语言的五行实现(Ruby,Java等),这将允许您验证示例数据是否正确。