Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Lachee1 · Jan 15, 2013 at 08:26 AM · imagefile-ioencryptionbytearray

[SOLVED] Bad PKCS7 While encrypting a file

I have found a C# encryption/decryption code on the internetnet. This code works really well until i try to decrypt a byte array.

What i am hoping to achive is a system that will encrypt a image, then on game load, decrypt it into assest. I would use this system as a form of updating, to keep all the images safe from any custom texture packing that might happen.

However, every time run a byte array through the code, i get this error: CryptographicException: Bad PKCS7 padding. Invalid length 206. at Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException (PaddingMode padding, Int32 length, Int32 position) [0x00000] in :0

   at Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x00000] in <filename unknown>:0 
 
   at Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x00000] in <filename unknown>:0 
 
   at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x00000] in <filename unknown>:0 
 
   at System.Security.Cryptography.CryptoStream.FlushFinalBlock () [0x00000] in <filename unknown>:0 
 
   at System.Security.Cryptography.CryptoStream.Close () [0x00000] in <filename unknown>:0 
 
   at ImageCrypt.Decrypt (System.Byte[] cipherData, System.Byte[] Key, System.Byte[] IV) [0x00033] in C:\Users\Public\Documents\Unity Projects\Protypes\Assets\Scripts\ImageCrypt.cs:248 
 
   at ImageCrypt.Decrypt (System.Byte[] cipherData, System.String Password) [0x00019] in C:\Users\Public\Documents\Unity Projects\Protypes\Assets\Scripts\ImageCrypt.cs:325 
 
   at ImageCrypt.Start () [0x0004c] in C:\Users\Public\Documents\Unity Projects\Protypes\Assets\Scripts\ImageCrypt.cs:23 
  
 (Filename: Assets/Scripts/ImageCrypt.cs Line: 248)

This is the code i am using, i have created the Start, Awake and the fileLoad functions myself, the rest is from the internet.

 using UnityEngine;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Text;
 using System.Security.Cryptography;
 using System.IO;
 
 #pragma warning disable 0618
 
 public class ImageCrypt : MonoBehaviour {
     
 
     public Texture2D tex; public ImageCrypt crypt; private byte[] o0; private void Awake(){ crypt = this; o0 = UTF8Encoding.UTF8.GetBytes ("12345678901234567890123456789012"); }
     
     void Start()
     {
         
         tex = new Texture2D (100,100);
         Encrypt(Application.dataPath + "/in.png", Application.dataPath + "/out.pixel", "lachee");
     
         byte[] Encrypted = loadByte(Application.dataPath + "/out.pixel");
         byte[] Decypted = Decrypt(Encrypted, "lachee");    
         tex.LoadImage(Decypted);
     }
      // Encrypt a byte array into a byte array using a key and an IV 
     public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV) 
     { 
         // Create a MemoryStream to accept the encrypted bytes 
         MemoryStream ms = new MemoryStream(); 
 
         // Create a symmetric algorithm. 
         // We are going to use Rijndael because it is strong and
         // available on all platforms. 
         // You can use other algorithms, to do so substitute the
         // next line with something like 
         //      TripleDES alg = TripleDES.Create(); 
         Rijndael alg = Rijndael.Create(); 
 
         // Now set the key and the IV. 
         // We need the IV (Initialization Vector) because
         // the algorithm is operating in its default 
         // mode called CBC (Cipher Block Chaining).
         // The IV is XORed with the first block (8 byte) 
         // of the data before it is encrypted, and then each
         // encrypted block is XORed with the 
         // following block of plaintext.
         // This is done to make encryption more secure. 
 
         // There is also a mode called ECB which does not need an IV,
         // but it is much less secure. 
         alg.Key = Key; 
         alg.IV = IV; 
 
         // Create a CryptoStream through which we are going to be
         // pumping our data. 
         // CryptoStreamMode.Write means that we are going to be
         // writing data to the stream and the output will be written
         // in the MemoryStream we have provided. 
         CryptoStream cs = new CryptoStream(ms, 
            alg.CreateEncryptor(), CryptoStreamMode.Write); 
 
         // Write the data and make it do the encryption 
         cs.Write(clearData, 0, clearData.Length); 
 
         // Close the crypto stream (or do FlushFinalBlock). 
         // This will tell it that we have done our encryption and
         // there is no more data coming in, 
         // and it is now a good time to apply the padding and
         // finalize the encryption process. 
         cs.Close(); 
 
         // Now get the encrypted data from the MemoryStream.
         // Some people make a mistake of using GetBuffer() here,
         // which is not the right way. 
         byte[] encryptedData = ms.ToArray();
 
         return encryptedData; 
     } 
 
     // Encrypt a string into a string using a password 
     //    Uses Encrypt(byte[], byte[], byte[]) 
 
     public static string Encrypt(string clearText, string Password) 
     { 
         // First we need to turn the input string into a byte array. 
         byte[] clearBytes = 
           System.Text.Encoding.Unicode.GetBytes(clearText); 
 
         // Then, we need to turn the password into Key and IV 
         // We are using salt to make it harder to guess our key
         // using a dictionary attack - 
         // trying to guess a password by enumerating all possible words. 
         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, 
             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 
 
         // Now get the key/IV and do the encryption using the
         // function that accepts byte arrays. 
         // Using PasswordDeriveBytes object we are first getting
         // 32 bytes for the Key 
         // (the default Rijndael key length is 256bit = 32bytes)
         // and then 16 bytes for the IV. 
         // IV should always be the block size, which is by default
         // 16 bytes (128 bit) for Rijndael. 
         // If you are using DES/TripleDES/RC2 the block size is
         // 8 bytes and so should be the IV size. 
         // You can also read KeySize/BlockSize properties off
         // the algorithm to find out the sizes. 
         byte[] encryptedData = Encrypt(clearBytes, 
                  pdb.GetBytes(32), pdb.GetBytes(16)); 
 
         // Now we need to turn the resulting byte array into a string. 
         // A common mistake would be to use an Encoding class for that.
         //It does not work because not all byte values can be
         // represented by characters. 
         // We are going to be using Base64 encoding that is designed
         //exactly for what we are trying to do. 
         return Convert.ToBase64String(encryptedData); 
 
     }
     
     // Encrypt bytes into bytes using a password 
     //    Uses Encrypt(byte[], byte[], byte[]) 
 
     public static byte[] Encrypt(byte[] clearData, string Password) 
     { 
         // We need to turn the password into Key and IV. 
         // We are using salt to make it harder to guess our key
         // using a dictionary attack - 
         // trying to guess a password by enumerating all possible words. 
         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, 
             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 
 
         // Now get the key/IV and do the encryption using the function
         // that accepts byte arrays. 
         // Using PasswordDeriveBytes object we are first getting
         // 32 bytes for the Key 
         // (the default Rijndael key length is 256bit = 32bytes)
         // and then 16 bytes for the IV. 
         // IV should always be the block size, which is by default
         // 16 bytes (128 bit) for Rijndael. 
         // If you are using DES/TripleDES/RC2 the block size is 8
         // bytes and so should be the IV size. 
         // You can also read KeySize/BlockSize properties off the
         // algorithm to find out the sizes. 
         return Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16)); 
 
     }
 
     // Encrypt a file into another file using a password 
     public static void Encrypt(string fileIn, 
                 string fileOut, string Password) 
     { 
 
         // First we are going to open the file streams 
         FileStream fsIn = new FileStream(fileIn, 
             FileMode.Open, FileAccess.Read); 
         FileStream fsOut = new FileStream(fileOut, 
             FileMode.OpenOrCreate, FileAccess.Write); 
 
         // Then we are going to derive a Key and an IV from the
         // Password and create an algorithm 
         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, 
             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 
 
         Rijndael alg = Rijndael.Create(); 
         alg.Key = pdb.GetBytes(32); 
         alg.IV = pdb.GetBytes(16); 
 
         // Now create a crypto stream through which we are going
         // to be pumping data. 
         // Our fileOut is going to be receiving the encrypted bytes. 
         CryptoStream cs = new CryptoStream(fsOut, 
             alg.CreateEncryptor(), CryptoStreamMode.Write); 
 
         // Now will will initialize a buffer and will be processing
         // the input file in chunks. 
         // This is done to avoid reading the whole file (which can
         // be huge) into memory. 
         int bufferLen = 4096; 
         byte[] buffer = new byte[bufferLen]; 
         int bytesRead; 
 
         do { 
             // read a chunk of data from the input file 
             bytesRead = fsIn.Read(buffer, 0, bufferLen); 
 
             // encrypt it 
             cs.Write(buffer, 0, bytesRead); 
         } while(bytesRead != 0); 
 
         // close everything 
 
         // this will also close the unrelying fsOut stream
         cs.Close(); 
         fsIn.Close();     
     } 
 
     // Decrypt a byte array into a byte array using a key and an IV 
     public static byte[] Decrypt(byte[] cipherData, 
                                 byte[] Key, byte[] IV) 
     { 
         // Create a MemoryStream that is going to accept the
         // decrypted bytes 
         MemoryStream ms = new MemoryStream(); 
 
         // Create a symmetric algorithm. 
         // We are going to use Rijndael because it is strong and
         // available on all platforms. 
         // You can use other algorithms, to do so substitute the next
         // line with something like 
         //     TripleDES alg = TripleDES.Create(); 
         Rijndael alg = Rijndael.Create(); 
 
         // Now set the key and the IV. 
         // We need the IV (Initialization Vector) because the algorithm
         // is operating in its default 
         // mode called CBC (Cipher Block Chaining). The IV is XORed with
         // the first block (8 byte) 
         // of the data after it is decrypted, and then each decrypted
         // block is XORed with the previous 
         // cipher block. This is done to make encryption more secure. 
         // There is also a mode called ECB which does not need an IV,
         // but it is much less secure. 
         alg.Key = Key; 
         alg.IV = IV; 
 
         // Create a CryptoStream through which we are going to be
         // pumping our data. 
         // CryptoStreamMode.Write means that we are going to be
         // writing data to the stream 
         // and the output will be written in the MemoryStream
         // we have provided. 
         CryptoStream cs = new CryptoStream(ms, 
             alg.CreateDecryptor(), CryptoStreamMode.Write); 
 
         // Write the data and make it do the decryption 
         cs.Write(cipherData, 0, cipherData.Length); 
 
         // Close the crypto stream (or do FlushFinalBlock). 
         // This will tell it that we have done our decryption
         // and there is no more data coming in, 
         // and it is now a good time to remove the padding
         // and finalize the decryption process. 
         cs.Close(); 
 
         // Now get the decrypted data from the MemoryStream. 
         // Some people make a mistake of using GetBuffer() here,
         // which is not the right way. 
         byte[] decryptedData = ms.ToArray(); 
 
         return decryptedData; 
     }
 
     // Decrypt a string into a string using a password 
     //    Uses Decrypt(byte[], byte[], byte[]) 
 
     public static string Decrypt(string cipherText, string Password) 
     { 
         // First we need to turn the input string into a byte array. 
         // We presume that Base64 encoding was used 
         byte[] cipherBytes = Convert.FromBase64String(cipherText); 
 
         // Then, we need to turn the password into Key and IV 
         // We are using salt to make it harder to guess our key
         // using a dictionary attack - 
         // trying to guess a password by enumerating all possible words. 
         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, 
             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
             0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 
 
         // Now get the key/IV and do the decryption using
         // the function that accepts byte arrays. 
         // Using PasswordDeriveBytes object we are first
         // getting 32 bytes for the Key 
         // (the default Rijndael key length is 256bit = 32bytes)
         // and then 16 bytes for the IV. 
         // IV should always be the block size, which is by
         // default 16 bytes (128 bit) for Rijndael. 
         // If you are using DES/TripleDES/RC2 the block size is
         // 8 bytes and so should be the IV size. 
         // You can also read KeySize/BlockSize properties off
         // the algorithm to find out the sizes. 
         byte[] decryptedData = Decrypt(cipherBytes, 
             pdb.GetBytes(32), pdb.GetBytes(16)); 
 
         // Now we need to turn the resulting byte array into a string. 
         // A common mistake would be to use an Encoding class for that.
         // It does not work 
         // because not all byte values can be represented by characters. 
         // We are going to be using Base64 encoding that is 
         // designed exactly for what we are trying to do. 
         return System.Text.Encoding.Unicode.GetString(decryptedData); 
     }
 
     // Decrypt bytes into bytes using a password 
     //    Uses Decrypt(byte[], byte[], byte[]) 
 
     public static byte[] Decrypt(byte[] cipherData, string Password) 
     { 
         // We need to turn the password into Key and IV. 
         // We are using salt to make it harder to guess our key
         // using a dictionary attack - 
         // trying to guess a password by enumerating all possible words. 
         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, 
             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 
 
         // Now get the key/IV and do the Decryption using the 
         //function that accepts byte arrays. 
         // Using PasswordDeriveBytes object we are first getting
         // 32 bytes for the Key 
         // (the default Rijndael key length is 256bit = 32bytes)
         // and then 16 bytes for the IV. 
         // IV should always be the block size, which is by default
         // 16 bytes (128 bit) for Rijndael. 
         // If you are using DES/TripleDES/RC2 the block size is
         // 8 bytes and so should be the IV size. 
 
         // You can also read KeySize/BlockSize properties off the
         // algorithm to find out the sizes. 
         return Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16)); 
     }
 
     // Decrypt a file into another file using a password 
     public static void Decrypt(string fileIn, 
                 string fileOut, string Password) 
     { 
     
         // First we are going to open the file streams 
         FileStream fsIn = new FileStream(fileIn,
                     FileMode.Open, FileAccess.Read); 
         FileStream fsOut = new FileStream(fileOut,
                     FileMode.OpenOrCreate, FileAccess.Write); 
   
         // Then we are going to derive a Key and an IV from
         // the Password and create an algorithm 
         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, 
             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 
         Rijndael alg = Rijndael.Create(); 
 
         alg.Key = pdb.GetBytes(32); 
         alg.IV = pdb.GetBytes(16); 
 
         // Now create a crypto stream through which we are going
         // to be pumping data. 
         // Our fileOut is going to be receiving the Decrypted bytes. 
         CryptoStream cs = new CryptoStream(fsOut, 
             alg.CreateDecryptor(), CryptoStreamMode.Write); 
   
         // Now will will initialize a buffer and will be 
         // processing the input file in chunks. 
         // This is done to avoid reading the whole file (which can be
         // huge) into memory. 
         int bufferLen = 4096; 
         byte[] buffer = new byte[bufferLen]; 
         int bytesRead; 
 
         do { 
             // read a chunk of data from the input file 
             bytesRead = fsIn.Read(buffer, 0, bufferLen); 
 
             // Decrypt it 
             cs.Write(buffer, 0, bytesRead); 
 
         } while(bytesRead != 0); 
 
         // close everything 
         cs.Close(); // this will also close the unrelying fsOut stream 
         fsIn.Close();     
     }
         
     public static byte[] loadByte(string fileIn)
     {
         /*    byte[] chunk = null;
             if ((fileIn.Length == 0) || !File.Exists(fileIn))
             {
                 Debug.LogError("Please provide an existing file name.");
             }
             else
             {
                 using (FileStream fs = new FileStream(fileIn, FileMode.Open, FileAccess.Read))
                 {
                     using (BinaryReader br = new BinaryReader(fs, new ASCIIEncoding()))
                     {
                         
     
                         chunk = br.ReadBytes(CHUNK_SIZE);
                       
                         
                     }
                 }
             }    
             return chunk;*/
         
         if (File.Exists(fileIn)){
             return File.ReadAllBytes(fileIn);
         }else{
             Debug.LogError("Cannot Read From A Null File");
             return null;
         }
     }
 }
 #pragma warning restore 0618
 
Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Joe78 · Mar 15, 2013 at 08:32 PM 0
Share

Hello,

excuse me, I'm just struggling around with encrypting/decrypting and got the same error. Do you $$anonymous$$d posting your working code ?

Thanks in advance. Joe

avatar image Lachee1 · Mar 18, 2013 at 12:36 AM 0
Share

Sure, no problems. I haven't used the files for a while so I'm not sure how they exactly work, but i'll give you what I have, they are located here: http://lacheedomain.netii.net/scripts/

You will need Cryptography.cs and Level$$anonymous$$asterCode.cs

Level$$anonymous$$asterCode.cs is actually part of one of my games, so I wish for you not to use any of the code unless link directly to the Cryptography.cs code, I spent a good amount of time on it you see, hate to see it stolen.

I may make a more use friendly Cryptography.cs version one day, however, I used another script for the majority of this one.

Have fun crypting. Note: $$anonymous$$y example codes save them as a picture.

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Lachee1 · Jan 15, 2013 at 09:11 AM

It was erroring because the file encryption was different to the byte decryption. I resolved it by encrypting the data THEN saving it using the File Stream

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SinisterRainbow · Oct 08, 2013 at 01:44 AM 0
Share

had the same error just pop up. $$anonymous$$udos to posting an answer and the question.

avatar image itsharshdeep · Jun 20, 2016 at 01:56 PM 0
Share

I don't know how. But I resolved this error by setting up my max character limit of inputfiled . I set limit to 30.

Strange!!!!

avatar image Elenesski · Sep 04, 2016 at 11:16 PM 0
Share

I also got this error when I tried to decrypt with a password that was different than what I encrypted with. (Hopefully that helps others too).

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Downsize/compress image on upload to Firebase? 0 Answers

Loading Textures during runtime and applying to Raw Images 2 Answers

XML Encryption 1 Answer

Bitmaps in unity 4 Answers

Is it possible to add an icon in text? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges