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); }
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); }
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; } }
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); } }
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; } }
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); }
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); } }
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); }
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); }
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); }
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); }
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); } }
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); }
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; } }
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); } }
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); } }