From 771930c460d1a53c9dd360f2eba10dbb0ae63471 Mon Sep 17 00:00:00 2001 From: MaxXor Date: Wed, 13 Aug 2014 22:59:57 +0200 Subject: [PATCH] Changed default traffic encryption from RC4 to AES -> speed & security improvements --- Client/Client.csproj | 1 - Client/Core/Client.cs | 5 +- Client/Core/Encryption/AES.cs | 194 +++++++++++++++++++++++++++------- Client/Core/Encryption/RC4.cs | 49 --------- Server/Core/Client.cs | 9 +- Server/Core/Encryption/AES.cs | 194 +++++++++++++++++++++++++++------- Server/Core/Encryption/RC4.cs | 49 --------- Server/Server.csproj | 1 - 8 files changed, 323 insertions(+), 179 deletions(-) delete mode 100644 Client/Core/Encryption/RC4.cs delete mode 100644 Server/Core/Encryption/RC4.cs diff --git a/Client/Client.csproj b/Client/Client.csproj index d5e2fc10..f604fd8d 100644 --- a/Client/Client.csproj +++ b/Client/Client.csproj @@ -93,7 +93,6 @@ - diff --git a/Client/Core/Client.cs b/Client/Core/Client.cs index beaef4d5..0c076c0b 100644 --- a/Client/Core/Client.cs +++ b/Client/Core/Client.cs @@ -11,6 +11,7 @@ using System.IO; using System.Net; using System.Net.Sockets; +using System.Text; using System.Threading; namespace Core @@ -55,7 +56,7 @@ private void OnClientRead(byte[] e) e = new LZ4.LZ4Decompressor32().Decompress(e); if (encryptionEnabled) - e = RC4.Decrypt(e, Settings.PASSWORD); + e = AES.Decrypt(e, Encoding.UTF8.GetBytes(Settings.PASSWORD)); using (MemoryStream deserialized = new MemoryStream(e)) { @@ -375,7 +376,7 @@ private void Send(byte[] data) return; if (encryptionEnabled) - data = RC4.Encrypt(data, Settings.PASSWORD); + data = AES.Encrypt(data, Encoding.UTF8.GetBytes(Settings.PASSWORD)); if (compressionEnabled) data = new LZ4.LZ4Compressor32().Compress(data); diff --git a/Client/Core/Encryption/AES.cs b/Client/Core/Encryption/AES.cs index de1dc0a8..d86c702f 100644 --- a/Client/Core/Encryption/AES.cs +++ b/Client/Core/Encryption/AES.cs @@ -7,64 +7,186 @@ namespace Core.Encryption { class AES { + private const int IVLENGTH = 16; + public static string Encrypt(string input, string keyy) { - RijndaelManaged rd = new RijndaelManaged(); + byte[] key, data = System.Text.Encoding.UTF8.GetBytes(input), encdata; - MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); - byte[] key = md5.ComputeHash(Encoding.UTF8.GetBytes(keyy)); + try + { + using (var md5 = new MD5CryptoServiceProvider()) + { + key = md5.ComputeHash(Encoding.UTF8.GetBytes(keyy)); + } - md5.Clear(); - rd.Key = key; - rd.GenerateIV(); + using (var ms = new MemoryStream()) + { + using (var rd = new RijndaelManaged()) + { + rd.Key = key; + rd.GenerateIV(); + byte[] iv = rd.IV; - byte[] iv = rd.IV; - MemoryStream ms = new MemoryStream(); + using (var cs = new CryptoStream(ms, rd.CreateEncryptor(), CryptoStreamMode.Write)) + { + ms.Write(iv, 0, iv.Length); // write first 16 bytes IV, followed by encrypted message + cs.Write(data, 0, data.Length); + cs.FlushFinalBlock(); + } - ms.Write(iv, 0, iv.Length); + iv = null; + } - CryptoStream cs = new CryptoStream(ms, rd.CreateEncryptor(), CryptoStreamMode.Write); - byte[] data = System.Text.Encoding.UTF8.GetBytes(input); + encdata = ms.ToArray(); + } - cs.Write(data, 0, data.Length); - cs.FlushFinalBlock(); + return Convert.ToBase64String(encdata); + } + catch + { + return string.Empty; + } + finally + { + encdata = null; + data = null; + key = null; + } + } - byte[] encdata = ms.ToArray(); + public static byte[] Encrypt(byte[] input, byte[] keyy) + { + byte[] key, data = input, encdata; - cs.Close(); - rd.Clear(); - ms.Close(); + try + { + using (var md5 = new MD5CryptoServiceProvider()) + { + key = md5.ComputeHash(keyy); + } - return Convert.ToBase64String(encdata); + using (var ms = new MemoryStream()) + { + using (var rd = new RijndaelManaged()) + { + rd.Key = key; + rd.GenerateIV(); + byte[] iv = rd.IV; + + using (var cs = new CryptoStream(ms, rd.CreateEncryptor(), CryptoStreamMode.Write)) + { + ms.Write(iv, 0, iv.Length); // write first 16 bytes IV, followed by encrypted message + cs.Write(data, 0, data.Length); + cs.FlushFinalBlock(); + } + + iv = null; + } + + encdata = ms.ToArray(); + } + + return encdata; + } + catch + { + return new byte[0]; + } + finally + { + encdata = null; + data = null; + key = null; + } } public static string Decrypt(string input, string keyy) { - RijndaelManaged rd = new RijndaelManaged(); - int rijndaelIvLength = 16; - MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); - byte[] key = md5.ComputeHash(Encoding.UTF8.GetBytes(keyy)); + byte[] key, data; + int i; - md5.Clear(); + try + { + using (var md5 = new MD5CryptoServiceProvider()) + { + key = md5.ComputeHash(Encoding.UTF8.GetBytes(keyy)); + } - byte[] encdata = Convert.FromBase64String(input); - MemoryStream ms = new MemoryStream(encdata); - byte[] iv = new byte[16]; + using (var ms = new MemoryStream(Convert.FromBase64String(input))) + { + using (var rd = new RijndaelManaged()) + { + byte[] iv = new byte[IVLENGTH]; + ms.Read(iv, 0, IVLENGTH); // read first 16 bytes for IV, followed by encrypted message + rd.IV = iv; + rd.Key = key; - ms.Read(iv, 0, rijndaelIvLength); - rd.IV = iv; - rd.Key = key; + using (var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read)) + { + data = new byte[ms.Length - IVLENGTH + 1]; + i = cs.Read(data, 0, data.Length); + } - CryptoStream cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read); + iv = null; + } + } - byte[] data = new byte[ms.Length - rijndaelIvLength + 1]; - int i = cs.Read(data, 0, data.Length); + return System.Text.Encoding.UTF8.GetString(data, 0, i); + } + catch + { + return string.Empty; + } + finally + { + data = null; + key = null; + } + } - cs.Close(); - rd.Clear(); - ms.Close(); + public static byte[] Decrypt(byte[] input, byte[] keyy) + { + byte[] key, data; + int i; - return System.Text.Encoding.UTF8.GetString(data, 0, i); + try + { + using (var md5 = new MD5CryptoServiceProvider()) + { + key = md5.ComputeHash(keyy); + } + + using (var ms = new MemoryStream(input)) + { + using (var rd = new RijndaelManaged()) + { + byte[] iv = new byte[IVLENGTH]; + ms.Read(iv, 0, IVLENGTH); // read first 16 bytes for IV, followed by encrypted message + rd.IV = iv; + rd.Key = key; + + using (var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read)) + { + data = new byte[ms.Length - IVLENGTH + 1]; + i = cs.Read(data, 0, data.Length); + } + + iv = null; + } + } + + return data; + } + catch + { + return new byte[0]; + } + finally + { + data = null; + key = null; + } } } } diff --git a/Client/Core/Encryption/RC4.cs b/Client/Core/Encryption/RC4.cs deleted file mode 100644 index 7255a6ae..00000000 --- a/Client/Core/Encryption/RC4.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Text; - -namespace Core.Encryption -{ - class RC4 - { - public static byte[] Encrypt(byte[] input, string key) - { - byte[] bKey = System.Text.Encoding.UTF8.GetBytes(key); - byte[] s = new byte[256]; - byte[] k = new byte[256]; - byte temp; - int i, j; - - for (i = 0; i < 256; i++) - { - s[i] = (byte)i; - k[i] = bKey[i % bKey.GetLength(0)]; - } - - j = 0; - for (i = 0; i < 256; i++) - { - j = (j + s[i] + k[i]) % 256; - temp = s[i]; - s[i] = s[j]; - s[j] = temp; - } - - i = j = 0; - for (int x = 0; x < input.GetLength(0); x++) - { - i = (i + 1) % 256; - j = (j + s[i]) % 256; - temp = s[i]; - s[i] = s[j]; - s[j] = temp; - int t = (s[i] + s[j]) % 256; - input[x] ^= s[t]; - } - return input; - } - - public static byte[] Decrypt(byte[] input, string key) - { - return Encrypt(input, key); - } - } -} diff --git a/Server/Core/Client.cs b/Server/Core/Client.cs index e1abb3b4..360e0e3e 100644 --- a/Server/Core/Client.cs +++ b/Server/Core/Client.cs @@ -10,6 +10,7 @@ using System.IO; using System.Net; using System.Net.Sockets; +using System.Text; using xRAT_2.Settings; namespace Core @@ -55,9 +56,9 @@ private void OnClientRead(byte[] e) if (compressionEnabled) e = new LZ4.LZ4Decompressor32().Decompress(e); - + if (encryptionEnabled) - e = RC4.Decrypt(e, XMLSettings.Password); + e = AES.Decrypt(e, Encoding.UTF8.GetBytes(XMLSettings.Password)); using (MemoryStream deserialized = new MemoryStream(e)) { @@ -363,14 +364,13 @@ public void Disconnect() } } - private void Send(byte[] data) { if (!Connected) return; if (encryptionEnabled) - data = RC4.Encrypt(data, XMLSettings.Password); + data = AES.Encrypt(data, Encoding.UTF8.GetBytes(XMLSettings.Password)); if (compressionEnabled) data = new LZ4.LZ4Compressor32().Compress(data); @@ -386,7 +386,6 @@ private void Send(byte[] data) } } - private void HandleSendQueue() { for (int i = 0; i < 5; i++) diff --git a/Server/Core/Encryption/AES.cs b/Server/Core/Encryption/AES.cs index de1dc0a8..d86c702f 100644 --- a/Server/Core/Encryption/AES.cs +++ b/Server/Core/Encryption/AES.cs @@ -7,64 +7,186 @@ namespace Core.Encryption { class AES { + private const int IVLENGTH = 16; + public static string Encrypt(string input, string keyy) { - RijndaelManaged rd = new RijndaelManaged(); + byte[] key, data = System.Text.Encoding.UTF8.GetBytes(input), encdata; - MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); - byte[] key = md5.ComputeHash(Encoding.UTF8.GetBytes(keyy)); + try + { + using (var md5 = new MD5CryptoServiceProvider()) + { + key = md5.ComputeHash(Encoding.UTF8.GetBytes(keyy)); + } - md5.Clear(); - rd.Key = key; - rd.GenerateIV(); + using (var ms = new MemoryStream()) + { + using (var rd = new RijndaelManaged()) + { + rd.Key = key; + rd.GenerateIV(); + byte[] iv = rd.IV; - byte[] iv = rd.IV; - MemoryStream ms = new MemoryStream(); + using (var cs = new CryptoStream(ms, rd.CreateEncryptor(), CryptoStreamMode.Write)) + { + ms.Write(iv, 0, iv.Length); // write first 16 bytes IV, followed by encrypted message + cs.Write(data, 0, data.Length); + cs.FlushFinalBlock(); + } - ms.Write(iv, 0, iv.Length); + iv = null; + } - CryptoStream cs = new CryptoStream(ms, rd.CreateEncryptor(), CryptoStreamMode.Write); - byte[] data = System.Text.Encoding.UTF8.GetBytes(input); + encdata = ms.ToArray(); + } - cs.Write(data, 0, data.Length); - cs.FlushFinalBlock(); + return Convert.ToBase64String(encdata); + } + catch + { + return string.Empty; + } + finally + { + encdata = null; + data = null; + key = null; + } + } - byte[] encdata = ms.ToArray(); + public static byte[] Encrypt(byte[] input, byte[] keyy) + { + byte[] key, data = input, encdata; - cs.Close(); - rd.Clear(); - ms.Close(); + try + { + using (var md5 = new MD5CryptoServiceProvider()) + { + key = md5.ComputeHash(keyy); + } - return Convert.ToBase64String(encdata); + using (var ms = new MemoryStream()) + { + using (var rd = new RijndaelManaged()) + { + rd.Key = key; + rd.GenerateIV(); + byte[] iv = rd.IV; + + using (var cs = new CryptoStream(ms, rd.CreateEncryptor(), CryptoStreamMode.Write)) + { + ms.Write(iv, 0, iv.Length); // write first 16 bytes IV, followed by encrypted message + cs.Write(data, 0, data.Length); + cs.FlushFinalBlock(); + } + + iv = null; + } + + encdata = ms.ToArray(); + } + + return encdata; + } + catch + { + return new byte[0]; + } + finally + { + encdata = null; + data = null; + key = null; + } } public static string Decrypt(string input, string keyy) { - RijndaelManaged rd = new RijndaelManaged(); - int rijndaelIvLength = 16; - MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); - byte[] key = md5.ComputeHash(Encoding.UTF8.GetBytes(keyy)); + byte[] key, data; + int i; - md5.Clear(); + try + { + using (var md5 = new MD5CryptoServiceProvider()) + { + key = md5.ComputeHash(Encoding.UTF8.GetBytes(keyy)); + } - byte[] encdata = Convert.FromBase64String(input); - MemoryStream ms = new MemoryStream(encdata); - byte[] iv = new byte[16]; + using (var ms = new MemoryStream(Convert.FromBase64String(input))) + { + using (var rd = new RijndaelManaged()) + { + byte[] iv = new byte[IVLENGTH]; + ms.Read(iv, 0, IVLENGTH); // read first 16 bytes for IV, followed by encrypted message + rd.IV = iv; + rd.Key = key; - ms.Read(iv, 0, rijndaelIvLength); - rd.IV = iv; - rd.Key = key; + using (var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read)) + { + data = new byte[ms.Length - IVLENGTH + 1]; + i = cs.Read(data, 0, data.Length); + } - CryptoStream cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read); + iv = null; + } + } - byte[] data = new byte[ms.Length - rijndaelIvLength + 1]; - int i = cs.Read(data, 0, data.Length); + return System.Text.Encoding.UTF8.GetString(data, 0, i); + } + catch + { + return string.Empty; + } + finally + { + data = null; + key = null; + } + } - cs.Close(); - rd.Clear(); - ms.Close(); + public static byte[] Decrypt(byte[] input, byte[] keyy) + { + byte[] key, data; + int i; - return System.Text.Encoding.UTF8.GetString(data, 0, i); + try + { + using (var md5 = new MD5CryptoServiceProvider()) + { + key = md5.ComputeHash(keyy); + } + + using (var ms = new MemoryStream(input)) + { + using (var rd = new RijndaelManaged()) + { + byte[] iv = new byte[IVLENGTH]; + ms.Read(iv, 0, IVLENGTH); // read first 16 bytes for IV, followed by encrypted message + rd.IV = iv; + rd.Key = key; + + using (var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read)) + { + data = new byte[ms.Length - IVLENGTH + 1]; + i = cs.Read(data, 0, data.Length); + } + + iv = null; + } + } + + return data; + } + catch + { + return new byte[0]; + } + finally + { + data = null; + key = null; + } } } } diff --git a/Server/Core/Encryption/RC4.cs b/Server/Core/Encryption/RC4.cs deleted file mode 100644 index 7255a6ae..00000000 --- a/Server/Core/Encryption/RC4.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Text; - -namespace Core.Encryption -{ - class RC4 - { - public static byte[] Encrypt(byte[] input, string key) - { - byte[] bKey = System.Text.Encoding.UTF8.GetBytes(key); - byte[] s = new byte[256]; - byte[] k = new byte[256]; - byte temp; - int i, j; - - for (i = 0; i < 256; i++) - { - s[i] = (byte)i; - k[i] = bKey[i % bKey.GetLength(0)]; - } - - j = 0; - for (i = 0; i < 256; i++) - { - j = (j + s[i] + k[i]) % 256; - temp = s[i]; - s[i] = s[j]; - s[j] = temp; - } - - i = j = 0; - for (int x = 0; x < input.GetLength(0); x++) - { - i = (i + 1) % 256; - j = (j + s[i]) % 256; - temp = s[i]; - s[i] = s[j]; - s[j] = temp; - int t = (s[i] + s[j]) % 256; - input[x] ^= s[t]; - } - return input; - } - - public static byte[] Decrypt(byte[] input, string key) - { - return Encrypt(input, key); - } - } -} diff --git a/Server/Server.csproj b/Server/Server.csproj index 9fbdfb11..4a2c2398 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -69,7 +69,6 @@ -