public void Encryption_Basic()
        {
            long nonce         = 10;
            var  messageString = "Test message to encrypt";
            var  message       = Encoding.UTF8.GetBytes("Test message to encrypt");
            var  encrypted     = _encryptionHelper.Encrypt(message, nonce);
            var  decrypted     = _encryptionHelper.Decrypt(encrypted, nonce);

            Assert.AreEqual(messageString, Encoding.UTF8.GetString(decrypted));
        }
        private void OnRespond(HTTPRequest request, HTTPResponse response)
        {
            isSending = false;

            string dataString;

            if (response == null)
            {
                Debug.Log("timeout");
                RespondData           = new RespondData();
                RespondData.errorCode = ErrorCode.Timeout;
                return;
            }

            if (response.Headers.ContainsKey("content-encoding"))
            {
                // normal flow
                try
                {
                    var decrypted    = _encryptionHelper.Decrypt(response.Data, nonce);
                    var decompressed = _encryptionHelper.GZipDecompress(decrypted);
                    dataString = _encryptionHelper.BytesToString(decompressed);
                }
                catch (Exception e)
                {
                    RespondData           = new RespondData();
                    RespondData.errorCode = ErrorCode.FailedToDecryptServerPayload;
                    return;
                }
            }
            else
            {
                // error flow
                dataString = response.DataAsText;
            }
            Debug.Log(dataString);

            RespondData = JsonUtility.FromJson <RespondData>(dataString);
            if (RespondData.errorCode == 0)
            {
                _OnRespondSuccess(RespondData);
            }
            else
            {
                _OnRespondError(RespondData);
            }
        }
Ejemplo n.º 3
0
        public void _request(string endPoint, RequestData requestData)
        {
            nonce++;

            isSending               = true;
            LastRequest             = new LastRequest();
            LastRequest.EndPoint    = endPoint;
            LastRequest.RequestData = requestData;

            // post
            requestData.version    = Version;
            requestData.versionKey = VersionKey;
            requestData.session    = user.session;
            requestData.cacheKey   = Convert.ToBase64String(md5.ComputeHash(Encoding.UTF8.GetBytes(JsonUtility.ToJson(requestData))));
            requestData.timestamp  = PredictedServerTimestamp;

            serverTimestamp = requestData.timestamp;

            string dataJson = localSendInvalidRequestData? "Invalid data":JsonUtility.ToJson(requestData);

            Byte[] payload       = _encryptionHelper.Encrypt(Encoding.UTF8.GetBytes(dataJson), nonce);
            string payloadBase64 = Convert.ToBase64String(payload);
            var    postForm      = new RawJsonForm();

            postForm.AddField("payloadBase64", payloadBase64);


            // signature
            Byte[] digest       = md5.ComputeHash(payload);
            string digestBase64 = Convert.ToBase64String(digest);

            Byte[] nonceByte   = BitConverter.GetBytes(nonce);
            Byte[] signMessage = new Byte[digest.Length + nonceByte.Length];
            Array.Copy(nonceByte, 0, signMessage, 0, nonceByte.Length);
            Array.Copy(digest, 0, signMessage, nonceByte.Length, digest.Length);
            string signedBase64 = Convert.ToBase64String(_encryptionHelper.SignMessage(signMessage));

            // query
            Dictionary <string, string> queryDict = new Dictionary <string, string>();

            queryDict.Add("signedBase64", localSendInvalidSignBase64? "invalid":signedBase64);
            queryDict.Add("token", token);
            queryDict.Add("remoteSendInvalidPayload", remoteSendInvalidPayload ? "true":"");
            queryDict.Add("remoteTimeout", remoteTimeout ? "true" : "");
            var query = getQuery(queryDict);


            // send request
            var         url         = $"{Host}{endPoint}?{query}";
            RespondData respondData = new RespondData();
            HTTPRequest request     = new HTTPRequest(new Uri(url), HTTPMethods.Post, (originalRequest, response) =>
            {
                isSending = false;

                if (response == null)
                {
                    RespondData           = new RespondData();
                    RespondData.errorCode = ErrorCode.Timeout;
                }
                else
                if (findHeader(response, "content-encoding") == "encrypted")
                {
                    try
                    {
                        Byte[] decryptedData = Unzip(_encryptionHelper.Decrypt(response.Data, nonce));

                        string decryptedStr = Encoding.UTF8.GetString(decryptedData);
                        respondData         = JsonUtility.FromJson <RespondData>(decryptedStr);

                        user = respondData.user;
                        if (respondData.token != null)
                        {
                            token = respondData.token;
                        }
                        receivedTimestamp = respondData.timestamp;
                        RespondData       = respondData;
                        UpdateCards(respondData.body);
                    }
                    catch (Exception ex)
                    {
                        RespondData           = new RespondData();
                        RespondData.errorCode = ErrorCode.FailedToDecryptServerPayload;
                    }
                    LastRequest = null;
                }
                else
                {
                    RespondData = JsonUtility.FromJson <RespondData>(response.DataAsText);
                }
            });

            request.Timeout = new TimeSpan(0, 0, Timeout);
            request.SetForm(postForm);
            request.Send();
        }
Ejemplo n.º 4
0
        public void _request(string endPoint, RequestData requestData)
        {
            nonce++;

            if (String.IsNullOrEmpty(requestData.cacheKey))
            {
                requestData.cacheKey = $"512343564564{UnityEngine.Random.Range(0,10000)}";
            }

            requestData.timestamp  = PredictedServerTimestamp;
            requestData.version    = Version;
            requestData.versionKey = VersionKey;
            requestData.session    = user.session;

            isSending = true;

            byte[]      payload  = _encryptionHelper.Encrypt(Encoding.ASCII.GetBytes(JsonUtility.ToJson(requestData)), nonce);
            RawJsonForm postForm = new RawJsonForm();

            if (localSendInvalidRequestData)
            {
                payload[0] = 55;
            }
            postForm.AddField("payloadBase64", Convert.ToBase64String(payload));


            Dictionary <string, string> dict = new Dictionary <string, string>();

            MD5    md5  = MD5.Create();
            string json = JsonUtility.ToJson(requestData);

            byte[] digest = md5.ComputeHash(payload);
            if (localSendInvalidSignBase64)
            {
                digest[0] = 55;
            }
            byte[] signMessage   = BitConverter.GetBytes(nonce).Concat(digest).ToArray();
            byte[] signedMessage = _encryptionHelper.SignMessage(signMessage);

            dict.Add("signedBase64", Convert.ToBase64String(signedMessage));
            dict.Add("token", token);
            if (remoteSendInvalidPayload)
            {
                dict.Add("remoteSendInvalidPayload", "true");
            }
            if (remoteTimeout)
            {
                dict.Add("remoteTimeout", "true");
            }
//            dict.Add("remoteTimeout", remoteTimeout? "1":"0");
//            dict.Add("remoteSendInvalidPayload", remoteSendInvalidPayload? "1":"0");

            Uri         url     = new Uri($"{Host}{endPoint}?{getQuery(dict)}");
            HTTPRequest request = new HTTPRequest(url, HTTPMethods.Post, (originalRequest, response) => {
                if (response == null)
                {
                    RespondData = new RespondData()
                    {
                        errorCode = ErrorCode.Timeout
                    };
                }
                else if (response.HasHeaderWithValue("Content-Encoding", "encrypted"))
                {
                    byte[] decrypted = _encryptionHelper.Decrypt(response.Data, nonce);

                    if (decrypted.Length <= 10)
                    {
                        RespondData = new RespondData()
                        {
                            errorCode = ErrorCode.FailedToDecryptServerPayload
                        };
                        isSending = false;
                        return;
                    }

                    Stream rs         = new MemoryStream(decrypted);
                    GZipStream stream = new GZipStream(rs, CompressionMode.Decompress);
                    MemoryStream us   = new MemoryStream();
                    byte[] respondArr = new byte[decrypted.Length];
                    stream.CopyTo(us);
//                                                                                 stream.CopyTo(us);
                    RespondData = JsonUtility.FromJson <RespondData>(Encoding.UTF8.GetString(us.ToArray()));

                    user  = RespondData.user;
                    cards = RespondData.body.cards;
                    card  = RespondData.body.card;

                    switch (endPoint)
                    {
                    case "/users/login":
                        serverTimestamp = receivedTimestamp = RespondData.timestamp;
                        token           = RespondData.token;
                        user            = RespondData.user;
                        break;

                    case "/cards/list":
                        cards = RespondData.body.cards;
                        card  = RespondData.body.card;

                        break;

                    case "/cards/create":
                        cards = RespondData.body.cards;
                        card  = RespondData.body.card;
                        break;

                    case "/cards/update":
                        cards = RespondData.body.cards;
                        card  = RespondData.body.card;
                        break;

                    case "/cards/delete":
                        cards = RespondData.body.cards;
                        card  = RespondData.body.card;
                        break;
                    }
                }
                else
                {
                    RespondData = JsonUtility.FromJson <RespondData>(response.DataAsText);
                }
                isSending = false;
            });

            request.Timeout = TimeSpan.FromSeconds(Timeout);
            request.SetForm(postForm);
            request.Send();
            LastRequest = new LastRequest()
            {
                EndPoint = endPoint, RequestData = requestData
            };
        }
        public void _request(string endPoint, RequestData requestData)
        {
            isSending = true;

            requestData.version    = Version;
            requestData.versionKey = VersionKey;
            requestData.deviceId   = DeviceId;
            requestData.timestamp  = PredictedServerTimestamp;
            requestData.session    = user.session;


            Byte[] payload       = _encryptionHelper.Encrypt(Encoding.UTF8.GetBytes(localSendInvalidRequestData ? "_" : "" + JsonUtility.ToJson(requestData)), ++nonce);
            string payloadBase64 = Convert.ToBase64String(payload);
            var    postForm      = new RawJsonForm();

            postForm.AddField("payloadBase64", payloadBase64);

            // signature
            Byte[] digest       = md5.ComputeHash(payload);
            Byte[] nonceByte    = BitConverter.GetBytes(nonce);
            Byte[] signMessage  = nonceByte.Concat(digest).ToArray();
            string signedBase64 = Convert.ToBase64String(_encryptionHelper.SignMessage(signMessage));

            // query
            Dictionary <string, string> queryDict = new Dictionary <string, string>();

            queryDict.Add("signedBase64", localSendInvalidSignBase64 ? "_" : "" + signedBase64);
            if (token != "")
            {
                queryDict.Add("token", token);
            }
            if (remoteTimeout)
            {
                queryDict.Add("remoteTimeout", "true");
            }
            if (remoteSendInvalidPayload)
            {
                queryDict.Add("remoteSendInvalidPayload", "true");
            }
            var query = getQuery(queryDict);


            LastRequest = new LastRequest()
            {
                EndPoint    = endPoint,
                RequestData = requestData
            };

            // send request
            var         url     = $"{Host}{endPoint}?{query}";
            HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post, (originalRequest, response) =>
            {
                if (response != null && response.IsSuccess)
                {
                    if (response.Headers.ContainsKey("content-encoding") && response.Headers["content-encoding"].Contains("encrypted"))
                    {
                        byte[] decrypted = _encryptionHelper.Decrypt(response.Data, nonce);
                        if (decrypted.Length > 10)
                        {
                            RespondData = JsonUtility.FromJson <RespondData>(
                                Encoding.UTF8.GetString(Decompress(decrypted)));


                            receivedTimestamp = RespondData.timestamp;
                            serverTimestamp   = RespondData.timestamp;

                            if (RespondData.timestamp - requestData.timestamp > Timeout)
                            {
                                RespondData.errorCode = ErrorCode.Timeout;
                            }
                            else
                            {
                                user = RespondData.user;
                                if (Mathf.Abs(PredictedServerTimestamp - receivedTimestamp) > 3600)
                                {
                                    RespondData.errorCode = ErrorCode.InvalidTimestamp;
                                }
                                else
                                {
                                    cards = RespondData.body.cards;
                                    card  = RespondData.body.card;
                                }

                                if (!String.IsNullOrEmpty(RespondData.token))
                                {
                                    token = RespondData.token;
                                }
                            }
                        }
                        else
                        {
                            RespondData = new RespondData()
                            {
                                errorCode = ErrorCode.FailedToDecryptServerPayload
                            };
                        }
                    }
                    else
                    {
                        RespondData = JsonUtility.FromJson <RespondData>(response.DataAsText);
                    }
                }
                else
                {
                    RespondData = new RespondData()
                    {
                        errorCode = ErrorCode.Timeout
                    };
                }

                isSending = false;
            });

            request.SetForm(postForm);
            request.Timeout = TimeSpan.FromSeconds(Timeout);
            request.Send();
        }
Ejemplo n.º 6
0
        public void _request(string endPoint, RequestData requestData)
        {
            nonce    += 1;
            isSending = true;

            if (LastRequest == null || endPoint != LastRequest.EndPoint || !requestData.Equals(LastRequest.RequestData))
            {
                requestData.cacheKey = UnityEngine.Random.Range(1000, 9999).ToString();
            }

            LastRequest             = new LastRequest();
            LastRequest.EndPoint    = endPoint;
            LastRequest.RequestData = requestData;

            requestData.version    = Version;
            requestData.versionKey = VersionKey;
            requestData.timestamp  = PredictedServerTimestamp;
            requestData.session    = user.session;
            //requestData.cacheKey

            // post
            Byte[] payload   = Encoding.UTF8.GetBytes(JsonUtility.ToJson(requestData));   // Json(requestData).toBytes(); new Byte[ 100 ]
            Byte[] encrypted = _encryptionHelper.Encrypt(payload, nonce);
            if (localSendInvalidRequestData)
            {
                encrypted = Encoding.UTF8.GetBytes("1234");
            }
            string payloadBase64 = Convert.ToBase64String(encrypted);   // "encryptWithChaCha(payload).toBase64()";
            var    postForm      = new RawJsonForm();

            postForm.AddField("payloadBase64", payloadBase64);

            // signature
            Byte[] digest      = md5.ComputeHash(encrypted);                 // md5(payload);new Byte[ 100 ]
            Byte[] nonceByte   = BitConverter.GetBytes(nonce);               // nonce to byte new Byte[ 8 ]
            Byte[] signMessage = new Byte[nonceByte.Length + digest.Length]; // nonceByte + digest
            Buffer.BlockCopy(nonceByte, 0, signMessage, 0, nonceByte.Length);
            Buffer.BlockCopy(digest, 0, signMessage, nonceByte.Length, digest.Length);
            if (localSendInvalidSignBase64)
            {
                signMessage = Encoding.UTF8.GetBytes("1234");
            }
            string signedBase64 = Convert.ToBase64String(_encryptionHelper.SignMessage(signMessage));     //"signWithChaCha(signMessage).toBase64()";

            // query
            Dictionary <string, string> queryDict = new Dictionary <string, string>();

            queryDict.Add("signedBase64", signedBase64);
            queryDict.Add("token", token);
            queryDict.Add("remoteTimeout", remoteTimeout.ToString());
            queryDict.Add("remoteSendInvalidPayload", remoteSendInvalidPayload.ToString());
            var query = getQuery(queryDict);

            // send request
            var         url         = $"{Host}{endPoint}?{query}";
            RespondData respondData = new RespondData();
            HTTPRequest request     = new HTTPRequest(new Uri(url), HTTPMethods.Post, (originalRequest, response) =>
            {
                isSending         = false;
                receivedTimestamp = CurrentTimestamp;

                if (response == null)
                {
                    this.RespondData      = new RespondData();
                    RespondData.errorCode = ErrorCode.Timeout;
                    return;
                }
                if (response.Data.Length <= 10)
                {
                    this.RespondData      = new RespondData();
                    RespondData.errorCode = ErrorCode.FailedToDecryptServerPayload;
                    return;
                }
                //Debug.Log( response.HasHeaderWithValue( "Content-Encoding", "encrypted" ) );
                const int size = 4096;
                byte[] buffer  = new byte[size];
                if (response.HasHeaderWithValue("Content-Encoding", "encrypted"))
                {
                    byte[] data;

                    using (GZipStream stream = new GZipStream(new MemoryStream(_encryptionHelper.Decrypt(response.Data, nonce)), CompressionMode.Decompress))
                    {
                        using (MemoryStream memory = new MemoryStream())
                        {
                            int count = 0;
                            do
                            {
                                count = stream.Read(buffer, 0, size);
                                if (count > 0)
                                {
                                    memory.Write(buffer, 0, count);
                                }
                            }while(count > 0);
                            data = memory.ToArray();
                        }
                    }
                    respondData = JsonUtility.FromJson <RespondData>(Encoding.UTF8.GetString(buffer));
                }
                else
                {
                    respondData = JsonUtility.FromJson <RespondData>(response.DataAsText);
                }
                this.RespondData = respondData;
                if (respondData.errorCode == 0)
                {
                    if (!String.IsNullOrEmpty(respondData.token))
                    {
                        this.token = respondData.token;
                    }
                    this.user            = respondData.user;
                    this.card            = respondData.body.card;
                    this.cards           = respondData.body.cards;
                    this.serverTimestamp = respondData.timestamp;
                }
            });

            request.SetForm(postForm);
            request.Timeout = TimeSpan.FromSeconds(Timeout);
            request.Send();
        }
        public void _request(string endPoint, RequestData requestData)
        {
            requestData.version    = Version;
            requestData.versionKey = VersionKey;
            requestData.timestamp  = CurrentTimestamp;

            if (serverTimestamp != 0)
            {
                requestData.timestamp = serverTimestamp;
            }

            nonce++;
            EncryptionHelper encryptionHelper = new EncryptionHelper();

            isSending = true;

            //post
            Byte[] payload = Encoding.UTF8.GetBytes(JsonUtility.ToJson(requestData));

            if (localSendInvalidRequestData)
            {
                payload = new byte[10];
            }


            string payloadBase64 = Convert.ToBase64String(encryptionHelper.Encrypt(payload, nonce));



            var postForm = new RawJsonForm();

            postForm.AddField("payloadBase64", payloadBase64);

            //signature
            Byte[] digest      = md5.ComputeHash(encryptionHelper.Encrypt(payload, nonce));
            Byte[] nonceByte   = BitConverter.GetBytes(nonce);
            Byte[] signMessage = new Byte[digest.Length + nonceByte.Length];

            if (!localSendInvalidSignBase64)
            {
                int counter = 0;
                for (int i = 0; i < nonceByte.Length; i++)
                {
                    signMessage[counter++] = nonceByte[i];
                }
                for (int i = 0; i < digest.Length; i++)
                {
                    signMessage[counter++] = digest[i];
                }
            }

            string signedBase64 = Convert.ToBase64String(encryptionHelper.SignMessage(signMessage));

            //query
            Dictionary <string, string> queryDict = new Dictionary <string, string>();

            queryDict.Add("signedBase64", signedBase64);
            queryDict.Add("token", token);

//			if( localSendInvalidRequestData )
//			{
//				Debug.Log("here");
            queryDict.Add("remoteSendInvalidPayload", remoteSendInvalidPayload.ToString());
            //}
            queryDict.Add("remoteTimeout", remoteTimeout.ToString());


            //Debug.LogWarning( P.T( queryDict ) ) ;
            var query = getQuery(queryDict);

            var url = $"{Host}{endPoint}?{query}";

            RespondData = new RespondData();

            LastRequest             = new LastRequest();
            LastRequest.EndPoint    = endPoint;
            LastRequest.RequestData = requestData;


            HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post, (originalRequest, response) =>
            {
                isSending = false;

                if (response == null)
                {
                    RespondData           = new RespondData();
                    RespondData.errorCode = ErrorCode.Timeout;
                    return;
                }



                //  Debug.LogWarning( response.DataAsText );
//				byte[] aa = Encoding.UTF8.GetBytes( response.DataAsText );
//				MemoryStream stream = new MemoryStream( encryptionHelper.Decrypt( aa, nonce ) );
//
//				GZipStream gZipStream = new GZipStream( stream, CompressionMode.Decompress );
//				byte[] buffer = new byte[ 100000 ];
//				int numRead = gZipStream.Read( buffer, 0, aa.Length );
//				Array.Resize( ref buffer, numRead );
//				Debug.Log("unzipped " + Encoding.UTF8.GetString( buffer ) );
//				Debug.Log("unzipped " + Convert.ToBase64String( buffer ) );

                //decrypt first unzip second
                byte[] unzipped = response.Data;

//Debug.Log( P.T( response.Headers ) );
                if (response.Headers.TryGetValue("content-encoding", out List <string> aaa))
                {
                    Debug.Log("unzipped");
                    unzipped = Decompress(encryptionHelper.Decrypt(response.Data, nonce));
                }

//				Debug.Log( "unzipped " + response.Data.Length +" "+ unzipped.Length );
//				Debug.Log("receiveJson " +String.Join( "", response.Data  )+" //"+ Encoding.UTF8.GetString( encryptionHelper.Decrypt( unzipped, nonce )) );

                if (response.Data.Length <= 10)
                {
                    RespondData           = new RespondData();
                    RespondData.errorCode = ErrorCode.FailedToDecryptServerPayload;
                    LastRequest           = null;
                }
                else
                {
                    RespondData = JsonUtility.FromJson <RespondData>(Encoding.UTF8.GetString(unzipped));
                    if (RespondData.token != null)
                    {
                        token = RespondData.token;
                        user  = RespondData.user;
                    }

                    cards             = RespondData.body.cards;
                    card              = RespondData.body.card;
                    receivedTimestamp = (long)RespondData.timestamp;

                    if (RespondData.errorCode != ErrorCode.Locked)
                    {
                        LastRequest         = null;
                        RespondData.isCache = true;
                    }

                    Debug.Log("errorCode " + RespondData.errorCode + " " + receivedTimestamp + " " + serverTimestamp + " " + CurrentTimestamp + " " + PredictedServerTimestamp);
                }
            });

            request.Timeout = new TimeSpan(0, 0, Timeout);
            request.SetForm(postForm);
            request.Send();
        }
        public void _request(string endPoint, RequestData requestData)
        {
            LastRequest = new LastRequest()
            {
                EndPoint = endPoint, RequestData = requestData
            };

            // post
            requestData.version    = Version;
            requestData.versionKey = VersionKey;
            requestData.cacheKey   = requestData.timestamp.ToString() + JsonUtility.ToJson(requestData);

            Byte[] payload = Encoding.UTF8.GetBytes(JsonUtility.ToJson(requestData)); // Json(requestData).toBytes();
            if (localSendInvalidRequestData)
            {
                payload = new byte[payload.Length];
            }

            Byte[] encryptedPayload = _encryptionHelper.Encrypt(payload, nonce);
            string payloadBase64    = Convert.ToBase64String(encryptedPayload);

            var postForm = new RawJsonForm();

            postForm.AddField("payloadBase64", payloadBase64);

            // signature
            Byte[] digest      = md5.ComputeHash(encryptedPayload);          // md5(payload);
            Byte[] nonceByte   = BitConverter.GetBytes(nonce);               // nonce to byte
            Byte[] signMessage = new byte[nonceByte.Length + digest.Length]; // nonceByte + digest
            if (!localSendInvalidSignBase64)
            {
                Array.Copy(nonceByte, signMessage, nonceByte.Length);
                Array.Copy(digest, 0, signMessage, nonceByte.Length, digest.Length);
            }

            string signedBase64 = Convert.ToBase64String(_encryptionHelper.SignMessage(signMessage));

            // query
            Dictionary <string, string> queryDict = new Dictionary <string, string>();

            queryDict.Add("signedBase64", signedBase64);
            queryDict.Add("token", token);
            queryDict.Add("remoteTimeout", remoteTimeout.ToString());
            queryDict.Add("remoteSendInvalidPayload", remoteSendInvalidPayload.ToString());
            var query = getQuery(queryDict);

            // send request
            var url = $"{Host}{endPoint}?{query}";

            Debug.Log(url);

            isSending = true;
            HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post, (originalRequest, response) =>
            {
                switch (originalRequest.State)
                {
                case HTTPRequestStates.TimedOut:
                    Debug.Log("TimedOut");
                    this.RespondData      = new RespondData();
                    RespondData.errorCode = ErrorCode.Timeout;
                    break;

                default:
                    try
                    {
                        string data;
                        if (response.HasHeaderWithValue("Content-Encoding", "encrypted"))
                        {
                            var decrypt = _encryptionHelper.Decrypt(response.Data, nonce);

                            using (MemoryStream memoryStream = new MemoryStream(decrypt))
                                using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
                                    using (MemoryStream reader = new MemoryStream())
                                    {
                                        gzipStream.CopyTo(reader);
                                        data = Encoding.UTF8.GetString(reader.ToArray());
                                    }
                        }
                        else
                        {
                            Debug.Log("FAILED: " + response.DataAsText);
                            data = response.DataAsText;
                        }

                        this.RespondData = JsonUtility.FromJson <RespondData>(data);
                        if (endPoint == "/users/login")
                        {
                            user  = RespondData.user;
                            token = RespondData.token;
                        }
                        else
                        {
                            cards = RespondData.body.cards;
                            card  = RespondData.body.card;
                        }
                        receivedTimestamp = RespondData.timestamp;
                        serverTimestamp   = RespondData.timestamp;
                    }
                    catch (Exception e)
                    {
                        Debug.Log(e.ToString());
                        this.RespondData      = new RespondData();
                        RespondData.errorCode = ErrorCode.FailedToDecryptServerPayload;
                    }
                    break;
                }

                isSending = false;
                nonce++;
            });

            request.Timeout = TimeSpan.FromMilliseconds(Timeout);
            request.SetForm(postForm);
            request.Send();
        }
        public void _request(string endPoint, RequestData requestData)
        {
            isSending = true;

            LastRequest             = new LastRequest();
            LastRequest.EndPoint    = endPoint;
            LastRequest.RequestData = requestData;

            long tmpNonce = nonce;

            //assign general request data
            requestData.version    = Version;
            requestData.versionKey = VersionKey;
            requestData.timestamp  = PredictedServerTimestamp;

            // post
            Byte[] payload       = Encoding.UTF8.GetBytes(JsonUtility.ToJson(requestData));
            string payloadBase64 = Convert.ToBase64String(localSendInvalidRequestData?
                                                          _encryptionHelper.Encrypt_Fake(payload, nonce) :
                                                          _encryptionHelper.Encrypt(payload, nonce));
            var postForm = new RawJsonForm();

            postForm.AddField("payloadBase64", payloadBase64);
            postForm.AddField("nonce", localSendInvalidRequestData? "0":nonce.ToString());

            // signature
            Byte[] digest = md5.ComputeHash(localSendInvalidRequestData?
                                            _encryptionHelper.Encrypt_Fake(payload, nonce) :
                                            _encryptionHelper.Encrypt(payload, nonce));
            Byte[] nonceByte   = BitConverter.GetBytes(nonce);
            Byte[] signMessage = new Byte[digest.Length + nonceByte.Length];
            Array.Copy(nonceByte, signMessage, nonceByte.Length);
            if (!localSendInvalidSignBase64)
            {
                Array.Copy(digest, 0, signMessage, nonceByte.Length, digest.Length);
            }
            string signedBase64 = Convert.ToBase64String(_encryptionHelper.SignMessage(signMessage));

            // query
            Dictionary <string, string> queryDict = new Dictionary <string, string>();

            queryDict.Add("signedBase64", signedBase64);
            queryDict.Add("token", token);
            queryDict.Add("remoteTimeout", remoteTimeout? "true" : "false");
            queryDict.Add("remoteSendInvalidPayload", remoteSendInvalidPayload? "true" : "false");
            var query = getQuery(queryDict);

            // send request
            var url = $"{Host}" + endPoint + $"?{query}";

            SetTimer(Timeout);
            RespondData = new RespondData();
            HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post, (originalRequest, response) =>
            {
                if (response.Data.Length == 10)
                {
                    RespondData.errorCode = RespondData.errorCode == 0? ErrorCode.FailedToDecryptServerPayload : RespondData.errorCode;
                }
                else if (response.HasHeaderWithValue("Content-Encoding", "encrypted"))
                {
                    var decrypted = _encryptionHelper.Decrypt(response.Data, tmpNonce);
                    RespondData   = JsonUtility.FromJson <RespondData>(Encoding.UTF8.GetString(Decompress(decrypted)));
                }
                else
                {
                    RespondData = JsonUtility.FromJson <RespondData>(response.DataAsText);
                }

                //assign user
                user.userId   = RespondData.user.userId == 0 ? user.userId : RespondData.user.userId;
                user.deviceId = RespondData.user.deviceId == null ? user.deviceId : RespondData.user.deviceId;
                user.session  = RespondData.user.session == null ? user.session : RespondData.user.session;

                //assign other server return value
                cards             = RespondData.body.cards == null ? cards : RespondData.body.cards;
                card              = RespondData.body.card;
                serverTimestamp   = RespondData.timestamp;
                receivedTimestamp = CurrentTimestamp;
                token             = RespondData.token == null ? token : RespondData.token;

                isSending = false;
            });

            request.SetForm(postForm);
            request.Send();

            nonce++;
        }
        public void _request(string endPoint, RequestData requestData)
        {
            RespondData      respondData      = new RespondData();
            EncryptionHelper encryptionHelper = new EncryptionHelper();

            {
                requestData.version    = Version;
                requestData.versionKey = VersionKey;
                requestData.timestamp  = CurrentTimestamp;
                requestData.session    = user.session;
                requestData.cacheKey   = requestData.cacheKey;
                requestData.cardId     = requestData.cardId;
                requestData.monsterId  = requestData.monsterId;
                requestData.exp        = requestData.exp;


                //login use only
                requestData.deviceId = DeviceId;
            }

            Byte[] payload       = JsonUtility.ToJson(requestData).GetASCIIBytes();
            byte[] encryptData   = encryptionHelper.Encrypt(payload, nonce, localSendInvalidRequestData);
            string payloadBase64 = Convert.ToBase64String(encryptData);
            var    postForm      = new RawJsonForm();

            postForm.AddField("payloadBase64", payloadBase64);

            // signature
            MD5 md5 = System.Security.Cryptography.MD5.Create();

            Byte[] digest       = md5.ComputeHash(encryptionHelper.Encrypt(payload, nonce, localSendInvalidRequestData)); //new Byte[100]; // md5(payload);
            Byte[] nonceByte    = BitConverter.GetBytes(nonce);                                                           //new Byte[8]; // nonce to byte
            Byte[] signMessage  = nonceByte.Concat(digest).ToArray();                                                     // nonceByte + digest
            string signedBase64 = Convert.ToBase64String(encryptionHelper.SignMessage(signMessage));

            if (localSendInvalidSignBase64)
            {
                signedBase64 = ":asdfjhasldkj" + signedBase64;
            }
            // query
            string tokenStr = "";

            if (string.IsNullOrEmpty(this.token))
            {
                this.token = "";
            }
            Dictionary <string, string> queryDict = new Dictionary <string, string>();

            queryDict.Add("signedBase64", signedBase64);
            queryDict.Add("token", this.token);
            queryDict.Add("remoteTimeout", this.remoteTimeout.ToString());
            queryDict.Add("remoteSendInvalidPayload", remoteSendInvalidPayload.ToString());
            var query = this.getQuery(queryDict);


            // send request
            var         url     = $"{_host}{endPoint}?{query}";
            HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post, (originalRequest, response) =>
            {
                bool contentEncrypted = false;
                switch (originalRequest.State)
                {
                case HTTPRequestStates.ConnectionTimedOut:
                case HTTPRequestStates.TimedOut:
                    this.RespondData.errorCode = ErrorCode.Timeout;
                    break;

                default:
                    if (response.Headers.ContainsKey("content-encoding"))
                    {
                        List <string> tmpOutput = response.Headers["content-encoding"];
                        if (tmpOutput.Contains("encrypted"))
                        {
                            contentEncrypted = true;
                        }
                    }
                    if (contentEncrypted)
                    {
                        try
                        {
                            var compressedStream = new MemoryStream(encryptionHelper.Decrypt(response.Data, nonce));
                            var zipStream        = new GZipStream(compressedStream, CompressionMode.Decompress);
                            var resultStream     = new MemoryStream();
                            zipStream.CopyTo(resultStream);
                            string outputString    = Encoding.UTF8.GetString(resultStream.ToArray());
                            respondData            = JsonUtility.FromJson <RespondData>(outputString);
                            this.receivedTimestamp = respondData.timestamp;

                            if ((this.CurrentTimestamp - this.serverTimestamp) > 3600 &&
                                !originalRequest.Uri.ToString().Contains("/login"))
                            {
                                this.RespondData.errorCode = ErrorCode.InvalidTimestamp;
                            }
                            else
                            {
                                this.RespondData = respondData;
                                if (!string.IsNullOrEmpty(respondData.token))
                                {
                                    this.token = respondData.token;
                                }

                                this.user            = respondData.user;
                                this.card            = respondData.body.card;
                                this.cards           = respondData.body.cards;
                                this.serverTimestamp = respondData.timestamp;
                            }
                        }
                        catch (Exception exception)
                        {
                            this.RespondData.errorCode = ErrorCode.FailedToDecryptServerPayload;
                            isSending = false;
                        }
                    }
                    else
                    {
                        try
                        {
                            string outputString        = Encoding.UTF8.GetString(response.Data);
                            respondData                = JsonUtility.FromJson <RespondData>(outputString);
                            this.RespondData.errorCode = respondData.errorCode;
                            isSending = false;
                        }
                        catch (Exception exception)
                        {
                            this.RespondData.errorCode = ErrorCode.FailedToDecryptServerPayload;
                            isSending = false;
                        }
                    }
                    break;
                }

                isSending = false;
            });

            request.SetForm(postForm);
            request.Timeout = new TimeSpan(0, 0, 0, this.Timeout);
            request.Send();


            LastRequest             = new LastRequest();
            LastRequest.EndPoint    = endPoint;
            LastRequest.RequestData = requestData;
        }