示例#1
0
        public override byte[] ClientUdpPostDecrypt(byte[] plaindata, int datalength, out int outlength)
        {
            if (datalength <= 8)
            {
                outlength = 0;
                return(plaindata);
            }
            MbedTLS.HMAC md5     = CreateHMAC(user_key);
            byte[]       md5data = md5.ComputeHash(plaindata, 0, datalength - 1);
            if (md5data[0] != plaindata[datalength - 1])
            {
                outlength = 0;
                return(plaindata);
            }
            md5     = CreateHMAC(Server.key);
            md5data = md5.ComputeHash(plaindata, datalength - 8, 7);
            int rand_len = UdpGetRandLen(random_server, md5data);

            outlength = datalength - rand_len - 8;
            encryptor = EncryptorFactory.GetEncryptor("chacha20", System.Convert.ToBase64String(user_key) + System.Convert.ToBase64String(md5data, 0, 16), false);
            {
                int    temp;
                byte[] iv = new byte[8];
                Array.Copy(Server.key, iv, 8);
                encryptor.Decrypt(iv, 8, plaindata, out temp);
            }
            encryptor.Decrypt(plaindata, outlength, plaindata, out outlength);
            return(plaindata);
        }
示例#2
0
        public override byte[] ClientUdpPreEncrypt(byte[] plaindata, int datalength, out int outlength)
        {
            byte[] outdata = new byte[datalength + 1024];
            if (user_key == null)
            {
                user_id = new byte[4];
                int index_of_split = Server.param.IndexOf(':');
                if (index_of_split > 0)
                {
                    try
                    {
                        uint user = uint.Parse(Server.param.Substring(0, index_of_split));
                        user_key = System.Text.Encoding.UTF8.GetBytes(Server.param.Substring(index_of_split + 1));
                        BitConverter.GetBytes(user).CopyTo(user_id, 0);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(LogLevel.Warn, $"Faild to parse auth param, fallback to basic mode. {ex}");
                    }
                }
                if (user_key == null)
                {
                    random.NextBytes(user_id);
                    user_key = Server.key;
                }
            }
            byte[] auth_data = new byte[3];
            random.NextBytes(auth_data);

            MbedTLS.HMAC md5      = CreateHMAC(Server.key);
            byte[]       md5data  = md5.ComputeHash(auth_data, 0, auth_data.Length);
            int          rand_len = UdpGetRandLen(random_client, md5data);

            byte[] rand_data = new byte[rand_len];
            random.NextBytes(rand_data);
            outlength = datalength + rand_len + 8;
            encryptor = EncryptorFactory.GetEncryptor("chacha20", System.Convert.ToBase64String(user_key) + System.Convert.ToBase64String(md5data, 0, 16), false);
            {
                byte[] iv = new byte[8];
                Array.Copy(Server.key, iv, 8);
                encryptor.SetIV(iv);
            }
            encryptor.Encrypt(plaindata, datalength, outdata, out datalength);
            rand_data.CopyTo(outdata, datalength);
            auth_data.CopyTo(outdata, outlength - 8);
            byte[] uid = new byte[4];
            for (int i = 0; i < 4; ++i)
            {
                uid[i] = (byte)(user_id[i] ^ md5data[i]);
            }
            uid.CopyTo(outdata, outlength - 5);
            {
                md5     = CreateHMAC(user_key);
                md5data = md5.ComputeHash(outdata, 0, outlength - 1);
                Array.Copy(md5data, 0, outdata, outlength - 1, 1);
            }
            return(outdata);
        }
示例#3
0
        public void PackData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            int cmdlen = 0;
            int rand_len;
            int start_pos = 2;

            if (send_back_cmd.Count > 0)
            {
                cmdlen += 2;
                //TODO
                send_tcp_mss = recv_tcp_mss;
                rand_len     = GetSendRandLen(datalength + cmdlen);
                outlength    = rand_len + datalength + cmdlen + 2;
                start_pos   += cmdlen;
                outdata[0]   = (byte)(send_back_cmd[0] ^ last_client_hash[14]);
                outdata[1]   = (byte)((send_back_cmd[0] >> 8) ^ last_client_hash[15]);
                outdata[2]   = (byte)(datalength ^ last_client_hash[12]);
                outdata[3]   = (byte)((datalength >> 8) ^ last_client_hash[13]);
                send_back_cmd.Clear();
            }
            else
            {
                rand_len   = GetSendRandLen(datalength);
                outlength  = rand_len + datalength + 2;
                outdata[0] = (byte)(datalength ^ last_client_hash[14]);
                outdata[1] = (byte)((datalength >> 8) ^ last_client_hash[15]);
            }
            {
                byte[] rnd_data = new byte[rand_len];
                random.NextBytes(rnd_data);
                if (datalength > 0)
                {
                    encryptor.Encrypt(data, datalength, data, out datalength);
                    Array.Copy(data, 0, outdata, start_pos, datalength);
                    if (rand_len > 0)
                    {
                        Array.Copy(data, 0, outdata, start_pos, datalength);
                    }
                }
                else
                {
                    rnd_data.CopyTo(outdata, start_pos);
                }
            }

            byte[] key = new byte[user_key.Length + 4];
            user_key.CopyTo(key, 0);
            BitConverter.GetBytes(pack_id).CopyTo(key, key.Length - 4);

            MbedTLS.HMAC md5 = CreateHMAC(key);
            ++pack_id;
            {
                byte[] md5data = md5.ComputeHash(outdata, 0, outlength);
                last_client_hash = md5data;
                Array.Copy(md5data, 0, outdata, outlength, 2);
                outlength += 2;
            }
        }
示例#4
0
        public void PackData(byte[] data, int datalength, int fulldatalength, byte[] outdata, out int outlength, bool nopadding = false)
        {
#if !PROTOCOL_STATISTICS
            int rand_len = GetRandLen(datalength, fulldatalength, nopadding) + 1;
#else
            const int overhead = 8;
            int       rand_len = GenRandLenFull((datalength == 0 ? 1 : datalength) + overhead + 1, fulldatalength, nopadding)
                                 - datalength - overhead;
#endif
            outlength = rand_len + datalength + 8;
            if (datalength > 0)
            {
                Array.Copy(data, 0, outdata, rand_len + 4, datalength);
            }
            outdata[0] = (byte)(outlength);
            outdata[1] = (byte)(outlength >> 8);
            byte[] key = new byte[user_key.Length + 4];
            user_key.CopyTo(key, 0);
            BitConverter.GetBytes(pack_id).CopyTo(key, key.Length - 4);
            {
                byte[] rnd_data = new byte[rand_len];
                random.NextBytes(rnd_data);
                rnd_data.CopyTo(outdata, 4);
            }

            MbedTLS.HMAC sha1 = CreateHMAC(key);
            {
                byte[] sha1data = sha1.ComputeHash(outdata, 0, 2);
                Array.Copy(sha1data, 0, outdata, 2, 2);
            }
            if (rand_len < 128)
            {
                outdata[4] = (byte)(rand_len);
            }
            else
            {
                outdata[4] = 0xFF;
                outdata[5] = (byte)(rand_len);
                outdata[6] = (byte)(rand_len >> 8);
            }
            ++pack_id;
            {
                byte[] sha1data = sha1.ComputeHash(outdata, 0, outlength - 4);
                Array.Copy(sha1data, 0, outdata, outlength - 4, 4);
            }
        }
示例#5
0
        public void PackData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            int rand_len = GetRandLen(datalength);

            outlength  = rand_len + datalength + 2;
            outdata[0] = (byte)(datalength ^ last_client_hash[14]);
            outdata[1] = (byte)((datalength >> 8) ^ last_client_hash[15]);
            {
                byte[] rnd_data = new byte[rand_len];
                random.NextBytes(rnd_data);
                encryptor.Encrypt(data, datalength, data, out datalength);
                if (datalength > 0)
                {
                    if (rand_len > 0)
                    {
                        int start_pos = GetRandStartPos(rand_len, random_client);
                        Array.Copy(data, 0, outdata, 2 + start_pos, datalength);
                        Array.Copy(rnd_data, 0, outdata, 2, start_pos);
                        Array.Copy(rnd_data, start_pos, outdata, 2 + start_pos + datalength, rand_len - start_pos);
                    }
                    else
                    {
                        Array.Copy(data, 0, outdata, 2, datalength);
                    }
                }
                else
                {
                    rnd_data.CopyTo(outdata, 2);
                }
            }

            byte[] key = new byte[user_key.Length + 4];
            user_key.CopyTo(key, 0);
            BitConverter.GetBytes(pack_id).CopyTo(key, key.Length - 4);

            MbedTLS.HMAC md5 = CreateHMAC(key);
            ++pack_id;
            {
                byte[] md5data = md5.ComputeHash(outdata, 0, outlength);
                last_client_hash = md5data;
                Array.Copy(md5data, 0, outdata, outlength, 2);
                outlength += 2;
            }
        }
示例#6
0
 public override byte[] ClientUdpPreEncrypt(byte[] plaindata, int datalength, out int outlength)
 {
     byte[] outdata = new byte[datalength + 8];
     byte[] uid     = new byte[4];
     if (user_key == null)
     {
         user_key = Server.key;
     }
     random.NextBytes(uid);
     outlength = datalength + 8;
     Array.Copy(plaindata, 0, outdata, 0, datalength);
     uid.CopyTo(outdata, datalength);
     {
         MbedTLS.HMAC sha1     = CreateHMAC(user_key);
         byte[]       sha1data = sha1.ComputeHash(outdata, 0, outlength - 4);
         Array.Copy(sha1data, 0, outdata, outlength - 4, 4);
     }
     return(outdata);
 }
示例#7
0
        public void PackData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            int rand_len = (datalength > 1200 ? 0 : pack_id > 4 ? random.Next(32) : (datalength > 900 ? random.Next(128) : random.Next(512))) + 1;

            outlength = rand_len + datalength + 8;
            if (datalength > 0)
            {
                Array.Copy(data, 0, outdata, rand_len + 4, datalength);
            }
            outdata[0] = (byte)(outlength);
            outdata[1] = (byte)(outlength >> 8);
            byte[] key = new byte[user_key.Length + 4];
            user_key.CopyTo(key, 0);
            BitConverter.GetBytes(pack_id).CopyTo(key, key.Length - 4);
            {
                byte[] rnd_data = new byte[rand_len];
                random.NextBytes(rnd_data);
                rnd_data.CopyTo(outdata, 4);
            }

            {
                MbedTLS.HMAC sha1     = CreateHMAC(key);
                byte[]       sha1data = sha1.ComputeHash(outdata, 0, 2);
                Array.Copy(sha1data, 0, outdata, 2, 2);
            }
            if (rand_len < 128)
            {
                outdata[4] = (byte)(rand_len);
            }
            else
            {
                outdata[4] = 0xFF;
                outdata[5] = (byte)(rand_len);
                outdata[6] = (byte)(rand_len >> 8);
            }
            ++pack_id;
            {
                MbedTLS.HMAC sha1     = CreateHMAC(key);
                byte[]       sha1data = sha1.ComputeHash(outdata, 0, outlength - 4);
                Array.Copy(sha1data, 0, outdata, outlength - 4, 4);
            }
        }
示例#8
0
 public override byte[] ClientUdpPostDecrypt(byte[] plaindata, int datalength, out int outlength)
 {
     if (datalength <= 4)
     {
         outlength = 0;
         return(plaindata);
     }
     MbedTLS.HMAC sha1     = CreateHMAC(user_key);
     byte[]       sha1data = sha1.ComputeHash(plaindata, 0, datalength - 4);
     if (sha1data[0] != plaindata[datalength - 4] ||
         sha1data[1] != plaindata[datalength - 3] ||
         sha1data[2] != plaindata[datalength - 2] ||
         sha1data[3] != plaindata[datalength - 1]
         )
     {
         outlength = 0;
         return(plaindata);
     }
     outlength = datalength - 4;
     return(plaindata);
 }
示例#9
0
        public override byte[] ClientUdpPostDecrypt(byte[] plaindata, int datalength, out int outlength)
        {
            if (datalength <= 8)
            {
                outlength = 0;
                return(plaindata);
            }
            MbedTLS.HMAC md5     = CreateHMAC(user_key);
            byte[]       md5data = md5.ComputeHash(plaindata, 0, datalength - 1);
            if (md5data[0] != plaindata[datalength - 1])
            {
                outlength = 0;
                return(plaindata);
            }
            md5     = CreateHMAC(Server.key);
            md5data = md5.ComputeHash(plaindata, datalength - 8, 7);
            int rand_len = UdpGetRandLen(random_server, md5data);

            outlength = datalength - rand_len - 8;
            encryptor = EncryptorFactory.GetEncryptor("rc4", Convert.ToBase64String(user_key) + Convert.ToBase64String(md5data, 0, 16));
            encryptor.Decrypt(plaindata, outlength, plaindata, out outlength);
            return(plaindata);
        }
示例#10
0
 public override byte[] ClientUdpPreEncrypt(byte[] plaindata, int datalength, out int outlength)
 {
     byte[] outdata = new byte[datalength + 8];
     if (user_key == null)
     {
         user_id = new byte[4];
         int index_of_split = Server.param.IndexOf(':');
         if (index_of_split > 0)
         {
             try
             {
                 uint user = uint.Parse(Server.param.Substring(0, index_of_split));
                 user_key = hash(System.Text.Encoding.UTF8.GetBytes(Server.param.Substring(index_of_split + 1)));
                 BitConverter.GetBytes(user).CopyTo(user_id, 0);
             }
             catch (Exception ex)
             {
                 // Logging.Log(LogLevel.Warn, $"Faild to parse auth param, fallback to basic mode. {ex}");
                 Logging.Log(LogLevel.Warn, string.Format("Faild to parse auth param, fallback to basic mode. {0}", ex));
             }
         }
         if (user_key == null)
         {
             random.NextBytes(user_id);
             user_key = Server.key;
         }
     }
     outlength = datalength + 8;
     Array.Copy(plaindata, 0, outdata, 0, datalength);
     user_id.CopyTo(outdata, datalength);
     {
         MbedTLS.HMAC sha1     = CreateHMAC(user_key);
         byte[]       sha1data = sha1.ComputeHash(outdata, 0, outlength - 4);
         Array.Copy(sha1data, 0, outdata, outlength - 4, 4);
     }
     return(outdata);
 }
示例#11
0
        public override byte[] ClientPostDecrypt(byte[] plaindata, int datalength, out int outlength)
        {
            byte[] outdata = new byte[recv_buf_len + datalength];
            Array.Copy(plaindata, 0, recv_buf, recv_buf_len, datalength);
            recv_buf_len += datalength;
            outlength     = 0;
            byte[] key = new byte[user_key.Length + 4];
            user_key.CopyTo(key, 0);
            while (recv_buf_len > 4)
            {
                BitConverter.GetBytes(recv_id).CopyTo(key, key.Length - 4);
                MbedTLS.HMAC sha1 = CreateHMAC(key);
                {
                    byte[] sha1data = sha1.ComputeHash(recv_buf, 0, 2);
                    if (sha1data[0] != recv_buf[2] || sha1data[1] != recv_buf[3])
                    {
                        throw new ObfsException("ClientPostDecrypt data error");
                    }
                }

                int len = (recv_buf[1] << 8) + recv_buf[0];
                if (len >= 8192 || len < 8)
                {
                    throw new ObfsException("ClientPostDecrypt data error");
                }
                if (len > recv_buf_len)
                {
                    break;
                }

                {
                    byte[] sha1data = sha1.ComputeHash(recv_buf, 0, len - 4);
                    if (sha1data[0] != recv_buf[len - 4] ||
                        sha1data[1] != recv_buf[len - 3] ||
                        sha1data[2] != recv_buf[len - 2] ||
                        sha1data[3] != recv_buf[len - 1]
                        )
                    {
                        throw new ObfsException("ClientPostDecrypt data uncorrect checksum");
                    }
                }

                {
                    ++recv_id;
                    int pos = recv_buf[4];
                    if (pos < 255)
                    {
                        pos += 4;
                    }
                    else
                    {
                        pos = ((recv_buf[6] << 8) | recv_buf[5]) + 4;
                    }
                    int outlen = len - pos - 4;
                    Util.Utils.SetArrayMinSize2(ref outdata, outlength + outlen);
                    Array.Copy(recv_buf, pos, outdata, outlength, outlen);
                    outlength    += outlen;
                    recv_buf_len -= len;
                    Array.Copy(recv_buf, len, recv_buf, 0, recv_buf_len);
                }
            }
            return(outdata);
        }
示例#12
0
        public void PackAuthData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            int rand_len    = (datalength > 400 ? random.Next(512) : random.Next(1024));
            int data_offset = rand_len + 16 + 4 + 4 + 7;

            outlength = data_offset + datalength + 4;
            byte[] encrypt      = new byte[24];
            byte[] encrypt_data = new byte[32];
            byte[] key          = new byte[Server.iv.Length + Server.key.Length];
            Server.iv.CopyTo(key, 0);
            Server.key.CopyTo(key, Server.iv.Length);

            AuthData authData = (AuthData)this.Server.data;

            {
                byte[] rnd_data = new byte[rand_len];
                random.NextBytes(rnd_data);
                rnd_data.CopyTo(outdata, data_offset - rand_len);
            }

            lock (authData)
            {
                if (authData.connectionID > 0xFF000000)
                {
                    authData.clientID = null;
                }
                if (authData.clientID == null)
                {
                    authData.clientID = new byte[4];
                    g_random.GetBytes(authData.clientID);
                    authData.connectionID = (UInt32)BitConverter.ToInt32(authData.clientID, 0) % 0xFFFFFD; // random.Next(0x1000000);
                }
                authData.connectionID += 1;
                Array.Copy(authData.clientID, 0, encrypt, 4, 4);
                Array.Copy(BitConverter.GetBytes(authData.connectionID), 0, encrypt, 8, 4);
            }
            UInt64 utc_time_second = (UInt64)Math.Floor(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
            UInt32 utc_time        = (UInt32)(utc_time_second);

            Array.Copy(BitConverter.GetBytes(utc_time), 0, encrypt, 0, 4);
            encrypt[12] = (byte)(outlength);
            encrypt[13] = (byte)(outlength >> 8);
            encrypt[14] = (byte)(rand_len);
            encrypt[15] = (byte)(rand_len >> 8);

            {
                byte[] uid = new byte[4];
                random.NextBytes(uid);
                user_key = Server.key;

                byte[] encrypt_key = user_key;

                Encryption.IEncryptor encryptor = Encryption.EncryptorFactory.GetEncryptor("aes-128-cbc", System.Convert.ToBase64String(encrypt_key) + SALT);
                int enc_outlen;

                encryptor.SetIV(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
                encryptor.Encrypt(encrypt, 16, encrypt_data, out enc_outlen);
                encryptor.Dispose();
                Array.Copy(encrypt_data, 16, encrypt, 4, 16);
                uid.CopyTo(encrypt, 0);
            }
            {
                MbedTLS.HMAC sha1     = CreateHMAC(key);
                byte[]       sha1data = sha1.ComputeHash(encrypt, 0, 20);
                Array.Copy(sha1data, 0, encrypt, 20, 4);
            }
            {
                byte[] rnd = new byte[1];
                random.NextBytes(rnd);
                rnd.CopyTo(outdata, 0);
                MbedTLS.HMAC sha1     = CreateHMAC(key);
                byte[]       sha1data = sha1.ComputeHash(rnd, 0, rnd.Length);
                Array.Copy(sha1data, 0, outdata, rnd.Length, 7 - rnd.Length);
            }
            encrypt.CopyTo(outdata, 7);
            Array.Copy(data, 0, outdata, data_offset, datalength);

            {
                MbedTLS.HMAC sha1     = CreateHMAC(user_key);
                byte[]       sha1data = sha1.ComputeHash(outdata, 0, outlength - 4);
                Array.Copy(sha1data, 0, outdata, outlength - 4, 4);
            }
        }
示例#13
0
        public override byte[] ClientPostDecrypt(byte[] plaindata, int datalength, out int outlength)
        {
            byte[] outdata = new byte[recv_buf_len + datalength];
            Array.Copy(plaindata, 0, recv_buf, recv_buf_len, datalength);
            recv_buf_len += datalength;
            outlength     = 0;
            byte[] key = new byte[user_key.Length + 4];
            user_key.CopyTo(key, 0);
            while (recv_buf_len > 4)
            {
                BitConverter.GetBytes(recv_id).CopyTo(key, key.Length - 4);
                MbedTLS.HMAC md5 = CreateHMAC(key);

                int data_len = ((recv_buf[1] ^ last_server_hash[15]) << 8) + (recv_buf[0] ^ last_server_hash[14]);
                int rand_len = GetRecvRandLen(data_len, random_server, last_server_hash);
                int len      = rand_len + data_len;
                if (len >= 4096)
                {
                    throw new ObfsException("ClientPostDecrypt data error");
                }
                if (len + 4 > recv_buf_len)
                {
                    break;
                }

                byte[] md5data = md5.ComputeHash(recv_buf, 0, len + 2);
                if (md5data[0] != recv_buf[len + 2] ||
                    md5data[1] != recv_buf[len + 3]
                    )
                {
                    throw new ObfsException("ClientPostDecrypt data uncorrect checksum");
                }

                {
                    int pos    = 2;
                    int outlen = data_len;
                    Util.Utils.SetArrayMinSize2(ref outdata, outlength + outlen);
                    byte[] data = new byte[outlen];
                    Array.Copy(recv_buf, pos, data, 0, outlen);
                    encryptor.Decrypt(data, outlen, data, out outlen);
                    last_server_hash = md5data;
                    if (recv_id == 1)
                    {
                        Server.tcp_mss = recv_tcp_mss = data[0] | (data[1] << 8);
                        pos            = 2;
                        outlen        -= 2;
                        send_back_cmd.Add(0xff00);
                    }
                    else
                    {
                        pos = 0;
                    }
                    Array.Copy(data, pos, outdata, outlength, outlen);
                    outlength    += outlen;
                    recv_buf_len -= len + 4;
                    Array.Copy(recv_buf, len + 4, recv_buf, 0, recv_buf_len);
                    ++recv_id;
                }
            }
            return(outdata);
        }
示例#14
0
        public void PackAuthData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            const int authhead_len = 4 + 8 + 4 + 16 + 4;

            byte[]           encrypt  = new byte[24];
            AuthDataAesChain authData = this.Server.data as AuthDataAesChain;

            lock (authData)
            {
                if (authData.connectionID > 0xFF000000)
                {
                    authData.clientID = null;
                }
                if (authData.clientID == null)
                {
                    authData.clientID = new byte[4];
                    g_random.GetBytes(authData.clientID);
                    authData.connectionID = (UInt32)BitConverter.ToInt32(authData.clientID, 0) % 0xFFFFFD;
                }
                authData.connectionID += 1;
                Array.Copy(authData.clientID, 0, encrypt, 4, 4);
                Array.Copy(BitConverter.GetBytes(authData.connectionID), 0, encrypt, 8, 4);
            }

            outlength = authhead_len;
            byte[] encrypt_data = new byte[32];
            byte[] key          = new byte[Server.iv.Length + Server.key.Length];
            Server.iv.CopyTo(key, 0);
            Server.key.CopyTo(key, Server.iv.Length);

            UInt64 utc_time_second = (UInt64)Math.Floor(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
            UInt32 utc_time        = (UInt32)(utc_time_second);

            Array.Copy(BitConverter.GetBytes(utc_time), 0, encrypt, 0, 4);

            encrypt[12]  = (byte)(Server.overhead);
            encrypt[13]  = (byte)(Server.overhead >> 8);
            send_tcp_mss = 1024; //random.Next(1024) + 400;
            recv_tcp_mss = send_tcp_mss;
            encrypt[14]  = (byte)(send_tcp_mss);
            encrypt[15]  = (byte)(send_tcp_mss >> 8);

            // first 12 bytes
            {
                byte[] rnd = new byte[4];
                random.NextBytes(rnd);
                rnd.CopyTo(outdata, 0);
                MbedTLS.HMAC md5     = CreateHMAC(key);
                byte[]       md5data = md5.ComputeHash(rnd, 0, rnd.Length);
                last_client_hash = md5data;
                Array.Copy(md5data, 0, outdata, rnd.Length, 8);
            }
            // uid & 16 bytes auth data
            {
                byte[] uid            = new byte[4];
                int    index_of_split = Server.param.IndexOf(':');
                if (index_of_split > 0)
                {
                    try
                    {
                        uint user = uint.Parse(Server.param.Substring(0, index_of_split));
                        user_key = System.Text.Encoding.UTF8.GetBytes(Server.param.Substring(index_of_split + 1));
                        BitConverter.GetBytes(user).CopyTo(uid, 0);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(LogLevel.Warn, $"Faild to parse auth param, fallback to basic mode. {ex}");
                    }
                }
                if (user_key == null)
                {
                    random.NextBytes(uid);
                    user_key = Server.key;
                }
                for (int i = 0; i < 4; ++i)
                {
                    uid[i] ^= last_client_hash[8 + i];
                }

                byte[] encrypt_key = user_key;

                Encryption.IEncryptor encryptor = Encryption.EncryptorFactory.GetEncryptor("aes-128-cbc", System.Convert.ToBase64String(encrypt_key) + SALT, false);
                int enc_outlen;

                encryptor.SetIV(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
                encryptor.Encrypt(encrypt, 16, encrypt_data, out enc_outlen);
                encryptor.Dispose();
                Array.Copy(encrypt_data, 0, encrypt, 4, 16);
                uid.CopyTo(encrypt, 0);
            }
            // final HMAC
            {
                MbedTLS.HMAC md5     = CreateHMAC(user_key);
                byte[]       md5data = md5.ComputeHash(encrypt, 0, 20);
                last_server_hash = md5data;
                Array.Copy(md5data, 0, encrypt, 20, 4);
            }
            encrypt.CopyTo(outdata, 12);
            encryptor = EncryptorFactory.GetEncryptor("chacha20", System.Convert.ToBase64String(user_key) + System.Convert.ToBase64String(last_client_hash, 0, 16), false);
            {
                byte[] iv = new byte[8];
                Array.Copy(last_client_hash, iv, 8);
                encryptor.SetIV(iv);
            }
            {
                int pack_outlength;
                encryptor.Decrypt(last_server_hash, 8, outdata, out pack_outlength);
            }

            // combine first chunk
            {
                byte[] pack_outdata = new byte[outdata.Length];
                int    pack_outlength;
                PackData(data, datalength, pack_outdata, out pack_outlength);
                Array.Copy(pack_outdata, 0, outdata, outlength, pack_outlength);
                outlength += pack_outlength;
            }
        }
示例#15
0
        public void PackAuthData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            int rand_len    = (datalength > 400 ? random.Next(512) : random.Next(1024));
            int data_offset = rand_len + 16 + 4 + 4 + 7;

            outlength = data_offset + datalength + 4;
            byte[] encrypt      = new byte[24];
            byte[] encrypt_data = new byte[32];
            byte[] key          = new byte[Server.iv.Length + Server.key.Length];
            Server.iv.CopyTo(key, 0);
            Server.key.CopyTo(key, Server.iv.Length);

            AuthData authData = (AuthData)this.Server.data;

            {
                byte[] rnd_data = new byte[rand_len];
                random.NextBytes(rnd_data);
                rnd_data.CopyTo(outdata, data_offset - rand_len);
            }

            lock (authData)
            {
                if (authData.connectionID > 0xFF000000)
                {
                    authData.clientID = null;
                }
                if (authData.clientID == null)
                {
                    authData.clientID = new byte[4];
                    g_random.GetBytes(authData.clientID);
                    authData.connectionID = (UInt32)BitConverter.ToInt32(authData.clientID, 0) % 0xFFFFFD; // random.Next(0x1000000);
                }
                authData.connectionID += 1;
                Array.Copy(authData.clientID, 0, encrypt, 4, 4);
                Array.Copy(BitConverter.GetBytes(authData.connectionID), 0, encrypt, 8, 4);
            }
            UInt64 utc_time_second = (UInt64)Math.Floor(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
            UInt32 utc_time        = (UInt32)(utc_time_second);

            Array.Copy(BitConverter.GetBytes(utc_time), 0, encrypt, 0, 4);
            encrypt[12] = (byte)(outlength);
            encrypt[13] = (byte)(outlength >> 8);
            encrypt[14] = (byte)(rand_len);
            encrypt[15] = (byte)(rand_len >> 8);

            {
                byte[] uid            = new byte[4];
                int    index_of_split = Server.param.IndexOf(':');
                if (index_of_split > 0)
                {
                    try
                    {
                        uint user = uint.Parse(Server.param.Substring(0, index_of_split));
                        user_key = hash(System.Text.Encoding.UTF8.GetBytes(Server.param.Substring(index_of_split + 1)));
                        BitConverter.GetBytes(user).CopyTo(uid, 0);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(LogLevel.Warn, $"Faild to parse auth param, fallback to basic mode. {ex}");
                    }
                }
                if (user_key == null)
                {
                    random.NextBytes(uid);
                    user_key = Server.key;
                }

                byte[] encrypt_key = user_key;

                Encryption.IEncryptor encryptor = Encryption.EncryptorFactory.GetEncryptor("aes-128-cbc", System.Convert.ToBase64String(encrypt_key) + SALT);
                int enc_outlen;

                encryptor.SetIV(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
                encryptor.Encrypt(encrypt, 16, encrypt_data, out enc_outlen);
                encryptor.Dispose();
                Array.Copy(encrypt_data, 16, encrypt, 4, 16);
                uid.CopyTo(encrypt, 0);
            }
            {
                MbedTLS.HMAC sha1     = CreateHMAC(key);
                byte[]       sha1data = sha1.ComputeHash(encrypt, 0, 20);
                Array.Copy(sha1data, 0, encrypt, 20, 4);
            }
            {
                byte[] rnd = new byte[1];
                random.NextBytes(rnd);
                rnd.CopyTo(outdata, 0);
                MbedTLS.HMAC sha1     = CreateHMAC(key);
                byte[]       sha1data = sha1.ComputeHash(rnd, 0, rnd.Length);
                Array.Copy(sha1data, 0, outdata, rnd.Length, 7 - rnd.Length);
            }
            encrypt.CopyTo(outdata, 7);
            Array.Copy(data, 0, outdata, data_offset, datalength);

            {
                MbedTLS.HMAC sha1     = CreateHMAC(user_key);
                byte[]       sha1data = sha1.ComputeHash(outdata, 0, outlength - 4);
                Array.Copy(sha1data, 0, outdata, outlength - 4, 4);
            }
        }
示例#16
0
        public void PackAuthData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            const int authhead_len = 7 + 4 + 16 + 4;
            const int overhead     = authhead_len + 4;

            byte[]         encrypt  = new byte[24];
            AuthDataAes128 authData = Server.data as AuthDataAes128;

            lock (authData)
            {
                if (authData.connectionID > 0xFF000000)
                {
                    authData.clientID = null;
                }
                if (authData.clientID == null)
                {
                    authData.clientID = new byte[4];
                    g_random.GetBytes(authData.clientID);
                    authData.connectionID = (uint)BitConverter.ToInt32(authData.clientID, 0) % 0xFFFFFD;
                }
                authData.connectionID += 1;
                Array.Copy(authData.clientID, 0, encrypt, 4, 4);
                Array.Copy(BitConverter.GetBytes(authData.connectionID), 0, encrypt, 8, 4);

                StatisticsInit(authData);
            }

#if !PROTOCOL_STATISTICS
            int rand_len = TrapezoidRandomInt(Server.tcp_mss - datalength - overhead + 1, -0.3); //(datalength > 400 ? LinearRandomInt(512) : LinearRandomInt(1024));
#else
            int rand_len = GenRandLenFull(datalength + overhead, datalength, false) - datalength - overhead;
#endif
            int data_offset = rand_len + authhead_len;
            outlength = data_offset + datalength + 4;
            byte[] encrypt_data = new byte[32];
            byte[] key          = new byte[Server.iv.Length + Server.key.Length];
            Server.iv.CopyTo(key, 0);
            Server.key.CopyTo(key, Server.iv.Length);

            {
                byte[] rnd_data = new byte[rand_len];
                random.NextBytes(rnd_data);
                rnd_data.CopyTo(outdata, data_offset - rand_len);
            }

            ulong utc_time_second = (ulong)Math.Floor(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
            uint  utc_time        = (uint)(utc_time_second);
            Array.Copy(BitConverter.GetBytes(utc_time), 0, encrypt, 0, 4);
            encrypt[12] = (byte)(outlength);
            encrypt[13] = (byte)(outlength >> 8);
            encrypt[14] = (byte)(rand_len);
            encrypt[15] = (byte)(rand_len >> 8);

            {
                byte[] uid            = new byte[4];
                int    index_of_split = Server.param.IndexOf(':');
                if (index_of_split > 0)
                {
                    try
                    {
                        uint user = uint.Parse(Server.param.Substring(0, index_of_split));
                        user_key = hash(System.Text.Encoding.UTF8.GetBytes(Server.param.Substring(index_of_split + 1)));
                        BitConverter.GetBytes(user).CopyTo(uid, 0);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(LogLevel.Warn, $"Faild to parse auth param, fallback to basic mode. {ex}");
                    }
                }
                if (user_key == null)
                {
                    random.NextBytes(uid);
                    user_key = Server.key;
                }

                byte[] encrypt_key = user_key;

                var encryptor = (StreamEncryptor)EncryptorFactory.GetEncryptor("aes-128-cbc", Convert.ToBase64String(encrypt_key) + SALT);
                int enc_outlen;

                encryptor.SetIV(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
                encryptor.Encrypt(encrypt, 16, encrypt_data, out enc_outlen);
                encryptor.Dispose();
                Array.Copy(encrypt_data, 0, encrypt, 4, 16);
                uid.CopyTo(encrypt, 0);
            }
            {
                MbedTLS.HMAC sha1     = CreateHMAC(key);
                byte[]       sha1data = sha1.ComputeHash(encrypt, 0, 20);
                Array.Copy(sha1data, 0, encrypt, 20, 4);
            }
            {
                byte[] rnd = new byte[1];
                random.NextBytes(rnd);
                rnd.CopyTo(outdata, 0);
                MbedTLS.HMAC sha1     = CreateHMAC(key);
                byte[]       sha1data = sha1.ComputeHash(rnd, 0, rnd.Length);
                Array.Copy(sha1data, 0, outdata, rnd.Length, 7 - rnd.Length);
            }
            encrypt.CopyTo(outdata, 7);
            Array.Copy(data, 0, outdata, data_offset, datalength);

            {
                MbedTLS.HMAC sha1     = CreateHMAC(user_key);
                byte[]       sha1data = sha1.ComputeHash(outdata, 0, outlength - 4);
                Array.Copy(sha1data, 0, outdata, outlength - 4, 4);
            }
        }