diff --git a/ErgometerLibrary/AESEncrypt.cs b/ErgometerLibrary/AESEncrypt.cs new file mode 100644 index 0000000..e17ba0d --- /dev/null +++ b/ErgometerLibrary/AESEncrypt.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace ErgometerLibrary +{ + static class AESEncrypt + { + // Change these keys + private static byte[] Key = { 47, 20, 192, 222, 214, 221, 193, 151, 182, 182, 20, 246, 80, 235, 182, 216, 116, 141, 188, 191, 13, 159, 1, 137, 151, 150, 29, 171, 240, 21, 251, 252 }; + private static byte[] Vector = { 147, 16, 78, 223, 97, 189, 43, 197, 244, 102, 242, 123, 184, 101, 75, 203 }; + + + private static ICryptoTransform EncryptorTransform, DecryptorTransform; + private static System.Text.UTF8Encoding UTFEncoder; + + static AESEncrypt() + { + //This is our encryption method + RijndaelManaged rm = new RijndaelManaged(); + + //Create an encryptor and a decryptor using our encryption method, key, and vector. + EncryptorTransform = rm.CreateEncryptor(Key, Vector); + DecryptorTransform = rm.CreateDecryptor(Key, Vector); + + //Used to translate bytes to text and vice versa + UTFEncoder = new System.Text.UTF8Encoding(); + } + + /// -------------- Two Utility Methods (not used but may be useful) ----------- + /// Generates an encryption key. + static public byte[] GenerateEncryptionKey() + { + //Generate a Key. + RijndaelManaged rm = new RijndaelManaged(); + rm.GenerateKey(); + return rm.Key; + } + + /// Generates a unique encryption vector + static public byte[] GenerateEncryptionVector() + { + //Generate a Vector + RijndaelManaged rm = new RijndaelManaged(); + rm.GenerateIV(); + return rm.IV; + } + + + /// ----------- The commonly used methods ------------------------------ + /// Encrypt some text and return a string suitable for passing in a URL. + public static string EncryptToString(string TextValue) + { + return ByteArrToString(Encrypt(TextValue)); + } + + /// Encrypt some text and return an encrypted byte array. + public static byte[] Encrypt(string TextValue) + { + //Translates our text value into a byte array. + Byte[] bytes = UTFEncoder.GetBytes(TextValue); + + //Used to stream the data in and out of the CryptoStream. + MemoryStream memoryStream = new MemoryStream(); + + /* + * We will have to write the unencrypted bytes to the stream, + * then read the encrypted result back from the stream. + */ + #region Write the decrypted value to the encryption stream + CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write); + cs.Write(bytes, 0, bytes.Length); + cs.FlushFinalBlock(); + #endregion + + #region Read encrypted value back out of the stream + memoryStream.Position = 0; + byte[] encrypted = new byte[memoryStream.Length]; + memoryStream.Read(encrypted, 0, encrypted.Length); + #endregion + + //Clean up. + cs.Close(); + memoryStream.Close(); + + return encrypted; + } + + /// The other side: Decryption methods + public static string DecryptString(string EncryptedString) + { + return Decrypt(StrToByteArray(EncryptedString)); + } + + /// Decryption when working with byte arrays. + public static string Decrypt(byte[] EncryptedValue) + { + #region Write the encrypted value to the decryption stream + MemoryStream encryptedStream = new MemoryStream(); + CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write); + decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length); + decryptStream.FlushFinalBlock(); + #endregion + + #region Read the decrypted value from the stream. + encryptedStream.Position = 0; + Byte[] decryptedBytes = new Byte[encryptedStream.Length]; + encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length); + encryptedStream.Close(); + #endregion + return UTFEncoder.GetString(decryptedBytes); + } + + /// Convert a string to a byte array. NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so). + // System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); + // return encoding.GetBytes(str); + // However, this results in character values that cannot be passed in a URL. So, instead, I just + // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100). + public static byte[] StrToByteArray(string str) + { + if (str.Length == 0) + throw new Exception("Invalid string value in StrToByteArray"); + + byte val; + byte[] byteArr = new byte[str.Length / 3]; + int i = 0; + int j = 0; + do + { + val = byte.Parse(str.Substring(i, 3)); + byteArr[j++] = val; + i += 3; + } + while (i < str.Length); + return byteArr; + } + + // Same comment as above. Normally the conversion would use an ASCII encoding in the other direction: + // System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + // return enc.GetString(byteArr); + public static string ByteArrToString(byte[] byteArr) + { + byte val; + string tempStr = ""; + for (int i = 0; i <= byteArr.GetUpperBound(0); i++) + { + val = byteArr[i]; + if (val < (byte)10) + tempStr += "00" + val.ToString(); + else if (val < (byte)100) + tempStr += "0" + val.ToString(); + else + tempStr += val.ToString(); + } + return tempStr; + } + } +} diff --git a/ErgometerLibrary/ErgometerLibrary.csproj b/ErgometerLibrary/ErgometerLibrary.csproj index ec808c5..b0e2aeb 100644 --- a/ErgometerLibrary/ErgometerLibrary.csproj +++ b/ErgometerLibrary/ErgometerLibrary.csproj @@ -46,6 +46,7 @@ + Component diff --git a/ErgometerLibrary/NetHelper.cs b/ErgometerLibrary/NetHelper.cs index 61e2060..00fbf04 100644 --- a/ErgometerLibrary/NetHelper.cs +++ b/ErgometerLibrary/NetHelper.cs @@ -32,7 +32,7 @@ namespace ErgometerLibrary try { StreamWriter wr = new StreamWriter(client.GetStream(), Encoding.Unicode); - wr.WriteLine(command); + wr.WriteLine(AESEncrypt.EncryptToString(command)); wr.Flush(); return true; } @@ -55,8 +55,18 @@ namespace ErgometerLibrary return net; */ - string str = ReadString(client); + string str; NetCommand net; + + try { + str = AESEncrypt.DecryptString(ReadString(client)); + } + catch (Exception e) + { + str = ""; + net = new NetCommand(NetCommand.CommandType.ERROR, 0); + } + if (str != "") try { net = NetCommand.Parse(str); diff --git a/ErgometerLibrary/Properties/AssemblyInfo.cs b/ErgometerLibrary/Properties/AssemblyInfo.cs index fbf1820..f721bc3 100644 --- a/ErgometerLibrary/Properties/AssemblyInfo.cs +++ b/ErgometerLibrary/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] +[assembly: AssemblyVersion("1.2.0.0")] [assembly: AssemblyFileVersion("1.0.3.7")]