/// <summary> /// 패킷을 보낼 수 있도록 가공한다. (zlib 압축 데이터 여기서 생성) /// </summary> /// <param name="key">Encryption key</param> /// <param name="hmacKey">HMAC generation key</param> /// <param name="prefix">The 6 bytes between the packet size and the IV</param> public void CompressAndAssemble(byte[] key, byte[] hmacKey, byte[] prefix, int count) { // 버퍼를 복구할 수 있도록. _buffer_before_assemble = _buffer; byte[] data = Compression.Compress(_buffer); byte[] Op = BitConverter.GetBytes((short)Opcode); byte[] Len = BitConverter.GetBytes((int)data.Length + 4); // 버퍼 + 압축내용 Array.Reverse(Op); Array.Reverse(Len); byte[] TempData; TempData = BytesUtil.ConcatBytes(Op, Len); TempData = BytesUtil.ConcatBytes(TempData, BitConverter.GetBytes((bool)true)); // 압축임 TempData = BytesUtil.ConcatBytes(TempData, BitConverter.GetBytes((int)_buffer.Length)); // 실제 크기 _buffer = BytesUtil.ConcatBytes(TempData, data); byte[] IV = CryptoGenerators.GenerateIV(); byte[] dataToAssemble = BytesUtil.ConcatBytes( BytesUtil.ConcatBytes(prefix, BitConverter.GetBytes(count)), BytesUtil.ConcatBytes(IV, CryptoFunctions.EncryptPacket(_buffer, key, IV))); _buffer = CryptoFunctions.ClearPacket(dataToAssemble, hmacKey); }
/// <summary> /// Receives the packet without size and HMAC hash and returns the packet ready to be sent /// </summary> /// <param name="data">Packet data (excluding the packet size and the HMAC hash)</param> /// <param name="hmacKey">HMAC Key</param> public static byte[] ClearPacket(byte[] data, byte[] hmacKey) { byte[] packetSize = new byte[2]; byte[] hmac = new byte[10]; packetSize = BitConverter.GetBytes((short)(2 + data.Length + 10)); hmac = CryptoGenerators.GenerateHmac(data, hmacKey); // Concatenates size + (prefix + IV + encrypted data) + hmac, composing the assembled packet return(BytesUtil.ConcatBytes(packetSize, BytesUtil.ConcatBytes(data, hmac))); }
/// <summary> /// Returns the compressed packet from the input data /// </summary> /// <param name="dataToCompress">Packet data to be compressed</param> public static byte[] CompressPacket(byte[] dataToCompress) { using (MemoryStream memoryStream = new MemoryStream()) { using (ZlibStream compressor = new ZlibStream(memoryStream, CompressionMode.Compress, CompressionLevel.Level1)) { compressor.Write(dataToCompress, 11, (dataToCompress.Length - 11)); } return(BytesUtil.ConcatBytes(BytesUtil.ReadBytes(dataToCompress, 0, 11), memoryStream.ToArray())); } }
/// <summary> /// Performs the data padding in the encryption process /// </summary> /// <param name="packetBuffer">Data to be encrypted</param> private static void PadPacket(ref byte[] packetBuffer) { int paddingLength = 8 + ((8 - packetBuffer.Length % 8) % 8); byte[] paddingBytes = new byte[paddingLength]; int i = 0; while (i < (paddingLength - 1)) { paddingBytes[i] = (byte)i; i++; } paddingBytes[i] = (byte)(i - 1); packetBuffer = BytesUtil.ConcatBytes(packetBuffer, paddingBytes); }
/// <summary> /// Gets the received packet data and returns the decrypted data /// </summary> /// <param name="packetBuffer">The packet data the way it was received</param> /// <param name="key">DES Encryption Key</param> /// <param name="IV">Initialization vector</param> public static byte[] DecryptPacket(byte[] packetBuffer, byte[] key, bool isHaveLength = false) { if (!isHaveLength) { packetBuffer = BytesUtil.ConcatBytes(BitConverter.GetBytes((short)(2 + packetBuffer.Length)), packetBuffer); } byte[] IV = BytesUtil.ReadBytes(packetBuffer, 8, 8); using (DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider()) { desProvider.Mode = CipherMode.CBC; desProvider.Padding = PaddingMode.None; using (ICryptoTransform decryptor = desProvider.CreateDecryptor(key, IV)) { byte[] rawData = decryptor.TransformFinalBlock(packetBuffer, 16, packetBuffer.Length - CryptoConstants.GC_HMAC_SIZE - 16); return(rawData); //return BytesUtil.ReadBytes(rawData, 0, (rawData.Length - (rawData[rawData.Length - 1] + 2))); } } }
/// <summary> /// Returns the uncompressed packet from the input data /// </summary> /// <param name="packetToUncompress">Packet data to be uncompressed</param> /// <returns></returns> public static byte[] UncompressPacket(byte[] packetToUncompress) { return(BytesUtil.ConcatBytes( BytesUtil.ReadBytes(packetToUncompress, 0, 11), ZlibStream.UncompressBuffer(BytesUtil.ReadBytes(packetToUncompress, 11, (packetToUncompress.Length - 11))))); }