public static KeyIV GetEncryptedKeyAndIV() { KeyIV keySalt; var password = "******"; var salt = "S@lt"; var rgb = new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(salt)); aesAlgorithm.Padding = PaddingMode.None; var rgbKey = rgb.GetBytes(aesAlgorithm.KeySize / 8); var rgbIV = rgb.GetBytes(aesAlgorithm.BlockSize / 8); //Encrypt the key and IV using (var rsaProvider = new RSACryptoServiceProvider()) { var setOaemPadding = true; keys = rsaProvider.ExportCspBlob(true); keySalt = new KeyIV(rsaProvider.Encrypt(rgbKey, setOaemPadding), rsaProvider.Encrypt(rgbIV, setOaemPadding)); } return(keySalt); }
/** * Genrates an AES key and IV * */ public KeyIV MakeKey(int KeySize, int BlockSize) { RijndaelManaged aesEncryption = new RijndaelManaged { KeySize = KeySize, BlockSize = BlockSize, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }; aesEncryption.GenerateIV(); aesEncryption.GenerateKey(); KeyIV keyIv = new KeyIV { Key = aesEncryption.Key, IV = aesEncryption.IV }; return(keyIv); }
/// <summary> /// Creates a packet and set its ID /// </summary> /// <param name="PacketId"></param> public PacketStream(ushort PacketId) { keyIV = Encryption.GenerateKeyIV(); int keyLen = keyIV.Key.Length; int ivLen = keyIV.IV.Length; this.inner = new MemoryStream(); // Write Blank space to have packet size assigned to later this.inner.Write(new byte[4], 0, 4); // Write the packetId this.inner.Write(BitConverter.GetBytes(PacketId), 0, 2); Random rand = new Random(); // Packet Header Structure // (int) Packet Size // (short) Packet ID // (short) KeyIV Key Length // (byte) Confusion Data // (byte) Confusion Data // (byte[]) KeyIV Key // (short) Confusion Data // (short) KeyIV IV Length // (byte[]) KeyIV Iv // Write the keyIV this.inner.Write(BitConverter.GetBytes((short)keyLen), 0, 2); this.inner.Write(BitConverter.GetBytes((byte)rand.Next(1, 255)), 0, 1); this.inner.Write(BitConverter.GetBytes((byte)rand.Next(1, 255)), 0, 1); this.inner.Write(keyIV.Key, 0, keyLen); this.inner.Write(BitConverter.GetBytes((short)rand.Next(1, 32767)), 0, 2); this.inner.Write(BitConverter.GetBytes((short)ivLen), 0, 2); this.inner.Write(keyIV.IV, 0, ivLen); }
/** * Sets an AES key and IV. * */ private void setKeyIV() { KeyGenerator keyGenerator = new KeyGenerator(); _keyIv = keyGenerator.MakeKey(_keySize, _blockSize); }
/// <summary> /// Receives data and split them into packets /// </summary> /// <param name="ar"></param> private void ReadCallback(IAsyncResult ar) { KeyIV keyIV = new KeyIV(); Connection client = (Connection)ar.AsyncState; if (client.Socket.Connected) { try { int totalBytes = client.Socket.EndReceive(ar); // If the stream actually has bytes in it if (totalBytes > 0) { int curOffset = 0; int bytesToRead = 0; int headerLen = 0; // If the packet size hasn't been defined in the client yet if (client.PacketSize == 0) { // Read the encrypted header length headerLen = BitConverter.ToInt32(client.Buffer.Take(4).ToArray(), 0); // Read the encrypted header byte[] encHeader = client.Buffer.Skip(4).Take(headerLen).ToArray(); // Generate a new dateTime key for encrypting the packet header string dtKey = DateTime.UtcNow.ToString("yyyyMMddHH"); rc4Cipher = new XRC4Cipher(dtKey); // Decode the header using the dtKey + rc4Cipher byte[] decodedHeader = rc4Cipher.DoCipher(ref encHeader, encHeader.Length); headerLen = decodedHeader.Length; // Write decoded header info to client.Data client.Data.Write(decodedHeader, curOffset, decodedHeader.Length); // If there is more than just the header info in this stream if (client.Offset + totalBytes > 4 + encHeader.Length) { // Define the packetSize by reading the size bytes from the client.Data buffer client.PacketSize = BitConverter.ToInt32(client.Data.ReadBytes(4, 0, true), 0); // TODO: Read my from client.Data? // Define the keyIV used for decoding the encrypted data int keyLen = client.Data.ReadInt16(6, true); keyIV.Key = client.Data.ReadBytes(keyLen, 10, true); int ivLen = client.Data.ReadInt16(12 + keyIV.Key.Length, true); keyIV.IV = client.Data.ReadBytes(ivLen, 14 + keyIV.Key.Length, true); } } // Set the amount of bytes to read by subtracting the current client offset from the decodedHeader.Length bytesToRead = (totalBytes - (4 + headerLen)); // Decode encoded information still in the buffer byte[] decodedArray = Encryption.DecryptBytes(client.Buffer.Skip(4 + headerLen).Take(bytesToRead).ToArray(), keyIV.Key, keyIV.IV); // Write decoded information to client.Data client.Data.Write(decodedArray, 0, decodedArray.Length); // Trigger the action associated to this packet PacketReceived(client, client.Data); client.Data = new PacketStream(); client.PacketSize = 0; client.Offset = 0; client.Socket.BeginReceive( client.Buffer, 0, PacketStream.MaxBuffer, SocketFlags.None, new AsyncCallback(ReadCallback), client ); } else { client.Socket.Close(); return; } } catch (Exception e) { client.Socket.Close(); Console.WriteLine("Client [{0}] disconected! (with errors)\n\t-Errors!\n\t-{1}.", client.ID, e.Message); } } }