private static KMSV5Request CreateKMSV5Request(byte[] kmsRequestData)
 {
     KMSV5Request kmsRequest = new KMSV5Request();
     using (MemoryStream stream = new MemoryStream(kmsRequestData))
     {
         using (BinaryReader binaryReader = new BinaryReader(stream))
         {
             kmsRequest.BodyLength1 = binaryReader.ReadUInt32();
             kmsRequest.BodyLength2 = binaryReader.ReadUInt32();
             kmsRequest.Version = binaryReader.ReadUInt32();
             kmsRequest.Salt = binaryReader.ReadBytes(16);
             kmsRequest.EncryptedRequest = binaryReader.ReadBytes(kmsRequestData.Length - 8 - 4 - 16 - 4);
             kmsRequest.Pad = binaryReader.ReadBytes(4);
         }
     }
     return kmsRequest;
 }
        private static byte[] DecryptV5(KMSV5Request kmsRequest)
        {
            byte[] iv = kmsRequest.Salt;
            byte[] encrypted =
                kmsRequest.Salt.Concat(kmsRequest.EncryptedRequest)
                .Concat(kmsRequest.Pad).ToArray();

            RijndaelManaged rijndaelManaged = new RijndaelManaged { Key = Key, IV = iv };

            byte[] decrypted;
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, rijndaelManaged.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(encrypted, 0, encrypted.Length);
                }
                decrypted = ms.ToArray();
            }
            return decrypted;
        }
        public byte[] HandleRequest(byte[] kmsRequestData)
        {
            KMSV5Request kmsv5Request = CreateKMSV5Request(kmsRequestData);
            byte[] decrypted = DecryptV5(kmsv5Request);
            byte[] decryptedSalt = decrypted.Take(16).ToArray();
            byte[] decryptedRequest = decrypted.Skip(16).ToArray();
            byte[] responseBytes = Server.ExecuteKMSServerLogic(decryptedRequest, Logger);

            byte[] randomSalt = Guid.NewGuid().ToByteArray();
            byte[] randomSaltHash = GetSHA265Hash(randomSalt);
            byte[] randomStuff = new byte[16];
            for (int i = 0; i < 16; i++)
            {
                randomStuff[i] = (byte)(decryptedSalt[i] ^ kmsv5Request.Salt[i] ^ randomSalt[i]);
            }
            byte[] responsedata = responseBytes.Concat(randomStuff).Concat(randomSaltHash).ToArray();
            byte[] encryptedResponseData = EncryptV5(responsedata, kmsv5Request.Salt);

            KMSV5Response kmsResponse = new KMSV5Response { Version = kmsv5Request.Version, Salt = kmsv5Request.Salt, Encrypted = encryptedResponseData };

            byte[] encryptedResponse = CreateKMSV5ResponseBytes(kmsResponse);
            return encryptedResponse;
        }