|  | @@ -8,7 +8,7 @@ namespace ArcToolkitCLI.Util
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      public static class Encryption
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        private static Random Random = new Random();
 | 
	
		
			
				|  |  | +        private static readonly Random Random = new Random();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          public static byte[] ReadKeyFromFile(string filename)
 | 
	
		
			
				|  |  |          {
 | 
	
	
		
			
				|  | @@ -48,11 +48,11 @@ namespace ArcToolkitCLI.Util
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          public static byte[] GenerateIV(byte[] ivSeed)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            uint[] seed = { 0x075BCD15, 0x159A55E5, 0x1F123BB5, BitConverter.ToUInt32(ivSeed, 0) ^ 0xBFBFBFBF };
 | 
	
		
			
				|  |  | +            uint[] seed = {0x075BCD15, 0x159A55E5, 0x1F123BB5, BitConverter.ToUInt32(ivSeed, 0) ^ 0xBFBFBFBF};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            for (int i = 0; i < 4; i++)
 | 
	
		
			
				|  |  | +            for (var i = 0; i < 4; i++)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                uint n = seed[0] ^ (seed[0] << 11);
 | 
	
		
			
				|  |  | +                var n = seed[0] ^ (seed[0] << 11);
 | 
	
		
			
				|  |  |                  seed[0] = seed[1];
 | 
	
		
			
				|  |  |                  seed[1] = seed[2];
 | 
	
		
			
				|  |  |                  seed[2] = seed[3];
 | 
	
	
		
			
				|  | @@ -72,14 +72,14 @@ namespace ArcToolkitCLI.Util
 | 
	
		
			
				|  |  |              var ivSeed = new byte[4];
 | 
	
		
			
				|  |  |              Array.Copy(encryptedBytes, encryptedBytes.Length - 4, ivSeed, 0, 4);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            byte[] iv = GenerateIV(ivSeed);
 | 
	
		
			
				|  |  | +            var iv = GenerateIV(ivSeed);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              using (var rijndael = new RijndaelManaged())
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  rijndael.Padding = PaddingMode.None;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                using (ICryptoTransform decryptor = rijndael.CreateDecryptor(key, iv))
 | 
	
		
			
				|  |  | -                using (var mem = new MemoryStream(encryptedBytes, 0, encryptedBytes.Length - extraDataSize - 5))
 | 
	
		
			
				|  |  | +                using (var decryptor = rijndael.CreateDecryptor(key, iv))
 | 
	
		
			
				|  |  | +                using (var mem = new MemoryStream(encryptedBytes, 0, encryptedBytes.Length - 5))
 | 
	
		
			
				|  |  |                  using (var stream = new CryptoStream(mem, decryptor, CryptoStreamMode.Read))
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  |                      var output = new byte[encryptedBytes.Length - extraDataSize - 5];
 | 
	
	
		
			
				|  | @@ -91,30 +91,38 @@ namespace ArcToolkitCLI.Util
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public static byte[] EncryptBytes(byte[] data, byte[] key, byte[] ivSeed = null, byte[] extraData = null)
 | 
	
		
			
				|  |  | +        public static byte[] EncryptBytes(byte[] data, byte[] key, byte[] ivSeed = null)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            if(extraData?.Length > 255)
 | 
	
		
			
				|  |  | -                throw new ArgumentException("Extra data cannot be larger than 255 bytes!", nameof(extraData));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |              if (ivSeed == null)
 | 
	
		
			
				|  |  |                  ivSeed = BitConverter.GetBytes(Random.Next());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            var iv = GenerateIV(ivSeed);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            byte[] iv = GenerateIV(ivSeed);
 | 
	
		
			
				|  |  | +            byte[] extraData = null;
 | 
	
		
			
				|  |  | +            if ((data.Length & 0xf) != 0) // Rijndael requires padding to 16 bytes in order to encrypt
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                var newSize = (data.Length & 0xfffffff0) + 0x10;
 | 
	
		
			
				|  |  | +                extraData = new byte[newSize - data.Length];
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              using (var rijndael = new RijndaelManaged())
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  rijndael.Padding = PaddingMode.None;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                using (ICryptoTransform encryptor = rijndael.CreateEncryptor(key, iv))
 | 
	
		
			
				|  |  | +                using (var encryptor = rijndael.CreateEncryptor(key, iv))
 | 
	
		
			
				|  |  |                  using (var mem = new MemoryStream())
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  |                      using (var stream = new CryptoStream(mem, encryptor, CryptoStreamMode.Write))
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  |                          stream.Write(data, 0, data.Length);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    byte extraLength = (byte) (extraData?.Length ?? 0);
 | 
	
		
			
				|  |  | -                    mem.Write(new []{ (byte)(extraLength ^ ivSeed[0])}, 0, 1);
 | 
	
		
			
				|  |  | -                    mem.Write(ivSeed, 0, ivSeed.Length);
 | 
	
		
			
				|  |  | +                        if (extraData != null)
 | 
	
		
			
				|  |  | +                            stream.Write(extraData, 0, extraData.Length);
 | 
	
		
			
				|  |  | +                        stream.Flush();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        var extraLength = (byte) (extraData?.Length ?? 0);
 | 
	
		
			
				|  |  | +                        mem.Write(new[] {(byte) (extraLength ^ ivSeed[0])}, 0, 1);
 | 
	
		
			
				|  |  | +                        mem.Write(ivSeed, 0, ivSeed.Length);
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      return mem.ToArray();
 | 
	
		
			
				|  |  |                  }
 |