/// <summary> /// Start network encryption. Automatically called by Login() if the server requests encryption. /// </summary> /// <returns>True if encryption was successful</returns> private bool StartEncryption(string uuid, string sessionID, byte[] token, string serverIDhash, byte[] serverKey) { System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); } if (serverIDhash != "-") { Console.WriteLine("Checking Session..."); if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey))) { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session."); return(false); } } //Encrypt the data byte[] key_enc = dataTypes.GetArray(RSAService.Encrypt(secretKey, false)); byte[] token_enc = dataTypes.GetArray(RSAService.Encrypt(token, false)); //Encryption Response packet SendPacket(0x01, dataTypes.ConcatBytes(key_enc, token_enc)); //Start client-side encryption socketWrapper.SwitchToEncrypted(secretKey); //Process the next packet int packetID = -1; List <byte> packetData = new List <byte>(); while (true) { ReadNextPacket(ref packetID, packetData); if (packetID == 0x00) //Login rejected { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(dataTypes.ReadNextString(packetData))); return(false); } else if (packetID == 0x02) //Login successful { login_phase = false; if (!pForge.CompleteForgeHandshake()) { return(false); } StartUpdating(); return(true); } else { HandlePacket(packetID, packetData); } } }
internal void HandleS01EncryptionRequest(S01EncryptionRequest s01EncryptionRequest) { waitingForEncryption = true; Console.WriteLine("Server is in online mode!"); RSACryptoServiceProvider rsaProvider = CryptoHandler.DecodeRSAPublicKey(s01EncryptionRequest.serverKey); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); Console.WriteLine("Keys generated"); if (s01EncryptionRequest.serverId != "-") { Console.WriteLine("Logging in to Mojang"); if (!Yggdrasil.SessionCheck(manager.loginParams.UUID, manager.loginParams.SessionId, CryptoHandler.getServerHash(s01EncryptionRequest.serverId, s01EncryptionRequest.serverKey, secretKey))) { Console.WriteLine("Mojang authentication failed"); return; } else { Console.WriteLine("Mojang authentication succesful"); } } manager.SendPacket(new C01EncryptionResponse(rsaProvider.Encrypt(secretKey, false), rsaProvider.Encrypt(s01EncryptionRequest.token, false))); manager.aesStream = CryptoHandler.getAesStream(manager.tcpClient.GetStream(), secretKey); manager.encrypted = true; }
private bool StartEncryption(string uuid, string username, string sessionID, byte[] token, string serverIDhash, byte[] serverKey) { System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); } if (serverIDhash != "-") { Console.WriteLine("Checking Session..."); if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey))) { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session."); return(false); } } //Encrypt the data byte[] key_enc = RSAService.Encrypt(secretKey, false); byte[] token_enc = RSAService.Encrypt(token, false); byte[] keylen = BitConverter.GetBytes((short)key_enc.Length); byte[] tokenlen = BitConverter.GetBytes((short)token_enc.Length); Array.Reverse(keylen); Array.Reverse(tokenlen); //Building the packet byte[] data = new byte[5 + (short)key_enc.Length + (short)token_enc.Length]; data[0] = 0xFC; keylen.CopyTo(data, 1); key_enc.CopyTo(data, 3); tokenlen.CopyTo(data, 3 + (short)key_enc.Length); token_enc.CopyTo(data, 5 + (short)key_enc.Length); //Send it back Send(data); //Getting the next packet byte[] pid = new byte[1]; Receive(pid, 0, 1, SocketFlags.None); if (pid[0] == 0xFC) { readData(4); s = CryptoHandler.getAesStream(c.GetStream(), secretKey); encrypted = true; return(true); } else { ConsoleIO.WriteLineFormatted("§8Invalid response to StartEncryption packet"); return(false); } }
/// <summary> /// Start network encryption. Automatically called by Login() if the server requests encryption. /// </summary> /// <returns>True if encryption was successful</returns> private bool StartEncryption(string uuid, string sessionID, byte[] token, string serverIDhash, byte[] serverKey) { System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); if (serverIDhash != "-") { Console.WriteLine("Checking Session..."); if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey))) { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session."); return(false); } } //Encrypt the data byte[] key_enc = RSAService.Encrypt(secretKey, false); byte[] token_enc = RSAService.Encrypt(token, false); byte[] key_len = getVarInt(key_enc.Length); byte[] token_len = getVarInt(token_enc.Length); //Encryption Response packet SendPacket(0x01, concatBytes(key_len, key_enc, token_len, token_enc)); //Start client-side encryption s = CryptoHandler.getAesStream(c.GetStream(), secretKey, this); encrypted = true; //Process the next packet int packetID = -1; byte[] packetData = new byte[] { }; while (true) { readNextPacket(ref packetID, ref packetData); if (packetID == 0x00) //Login rejected { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(readNextString(ref packetData))); return(false); } else if (packetID == 0x02) //Login successful { login_phase = false; StartUpdating(); return(true); } else { handlePacket(packetID, packetData); } } }
/// <summary> /// Start network encryption. Automatically called by Login() if the server requests encryption. /// </summary> /// <returns>True if encryption was successful</returns> private bool StartEncryption(string uuid, string sessionID, byte[] token, string serverIDhash, byte[] serverKey) { System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); if (serverIDhash != "-") { Console.WriteLine("Checking Session..."); if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey))) { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session."); return(false); } } //Encrypt the data byte[] key_enc = RSAService.Encrypt(secretKey, false); byte[] token_enc = RSAService.Encrypt(token, false); byte[] key_len = BitConverter.GetBytes((short)key_enc.Length); Array.Reverse(key_len); byte[] token_len = BitConverter.GetBytes((short)token_enc.Length); Array.Reverse(token_len); //Encryption Response packet byte[] packet_id = getVarInt(0x01); byte[] encryption_response = concatBytes(packet_id, key_len, key_enc, token_len, token_enc); byte[] encryption_response_tosend = concatBytes(getVarInt(encryption_response.Length), encryption_response); Send(encryption_response_tosend); //Start client-side encryption s = CryptoHandler.getAesStream(c.GetStream(), secretKey, this); encrypted = true; //Read and skip the next packet int received_packet_size = readNextVarInt(); int received_packet_id = readNextVarInt(); bool encryption_success = (received_packet_id == 0x02); if (received_packet_id == 0) { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(readNextString())); } else { readData(received_packet_size - getVarInt(received_packet_id).Length); } if (encryption_success) { StartUpdating(); } return(encryption_success); }
public bool SwitchToEncrypted(string serverID, byte[] Serverkey, byte[] token) { if (ServerData.OnlineMode) { var crypto = CryptoHandler.DecodeRSAPublicKey(Serverkey); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); byte[] key_enc = crypto.Encrypt(secretKey, false); byte[] token_enc = crypto.Encrypt(token, false); //Console.WriteLine(key_enc.Length + " " + token_enc.Length); SendPacket(0x01, concatBytes(getArray(key_enc), getArray(token_enc))); this.s = CryptoHandler.getAesStream(c.GetStream(), secretKey); encrypted = true; int packetID = -1; List <byte> packetData = new List <byte>(); while (true) { readNextPacket(ref packetID, packetData); if (packetID == 0x00) { handler.OnConnectionLost(Conn.DisconnectReason.LoginRejected, readNextString(packetData)); return(false); } else if (packetID == 0x02)//Logined { Debug.Log("Login Success"); login_phase = false; handler.OnLogin(packetData); StartUpdating(); return(true); } else { if (packetID == 0x03 && login_phase) { if (protocolversion >= MCVersion.MC18Version) { compression_treshold = readNextVarInt(packetData); } } handler.receivePacket(packetID, packetData); } } } else { handler.OnConnectionLost(Conn.DisconnectReason.LoginRejected, ServerData.MsgEncryptReject); } return(false); }
/// <summary> /// Gets the next packet from the server /// </summary> /// <returns></returns> public PacketData ReadNextPacket() { int packetId; byte[] payload; lock (_streamReadLock) { int length = VarInt.ReadNext(ReadBytes); List <byte> buffer = new List <byte>(); // check if data is compressed if (_compressionThreshold >= 0) { int dataLength = VarInt.ReadNext(ReadBytes); length -= VarInt.GetBytes(dataLength).Length; // remove size of data length from rest of packet length if (dataLength != 0) { byte[] compressedBuffer = ReadBytes(length); buffer.AddRange(ZlibStream.UncompressBuffer(compressedBuffer)); } else { buffer.AddRange(ReadBytes(length)); } } else { buffer.AddRange(ReadBytes(length)); } packetId = VarInt.ReadNext(buffer); payload = buffer.ToArray(); } // handles some stuff during login phase if (State == ProtocolState.LOGIN) { // handle compression packet if (packetId == (int)ClientboundIDs.LogIn_SetCompression) { _compressionThreshold = VarInt.ReadNext(new List <byte>(payload)); return(ReadNextPacket()); } // handle protocol encryption packet if (packetId == (int)ClientboundIDs.LogIn_EncryptionRequest) { var encRequestPkt = new EncryptionRequestPacket() { Payload = payload }; var aesSecret = CryptoHandler.GenerateSharedSecret(); var authHash = CryptoHandler.SHAHash(Encoding.ASCII.GetBytes(encRequestPkt.ServerID).Concat(aesSecret, encRequestPkt.PublicKey)); Debug.Log($"Sending hash to Mojang servers: {authHash}"); // check session with mojang if (!MojangAPI.JoinServer(authHash)) { throw new UnityException("Invalid session. (Try restarting game or relogging into Minecraft account)"); } // use pub key to encrypt shared secret using (var rsaProvider = CryptoHandler.DecodeRSAPublicKey(encRequestPkt.PublicKey)) { byte[] encSecret = rsaProvider.Encrypt(aesSecret, false); byte[] encToken = rsaProvider.Encrypt(encRequestPkt.VerifyToken, false); // respond to server with private key var responsePkt = new EncryptionResponsePacket() { SharedSecret = encSecret, VerifyToken = encToken }; WritePacket(responsePkt); // enable aes encryption _aesStream = new AesStream(Client.GetStream(), aesSecret); _encrypted = true; // read the next packet return(ReadNextPacket()); } } } return(new PacketData { ID = packetId, Payload = payload }); }