示例#1
0
        private void HandleEncryption(EncryptionRequestPacket packet)
        {
            var random = RandomNumberGenerator.Create();

            _sharedSecret = new byte[16];
            random.GetBytes(_sharedSecret);

            if (packet.ServerId != "")
            {
                throw new NotImplementedException("Online mode is not implemented");
            }

            var parser = new AsnKeyParser(packet.PublicKey);
            var key    = parser.ParseRSAPublicKey();

            // Encrypt shared secret and verification token
            var crypto = new RSACryptoServiceProvider();

            crypto.ImportParameters(key);
            WritePacket(new EncryptionResponsePacket
            {
                SharedSecret = crypto.Encrypt(_sharedSecret, false),
                VerifyToken  = crypto.Encrypt(packet.VerifyToken, false),
            });

            _baseStream = new AesStream(_networkStream, _sharedSecret);
            _writer     = new MinecraftStreamWriter(_baseStream);
            _reader     = new MinecraftStreamReader(_baseStream);
        }
示例#2
0
        /// <summary>
        /// Compose and send an encryption request packet to the server
        /// </summary>
        private void SendEncryptionRequest()
        {
            // Create the encryption request packet
            EncryptionRequestPacket packet = new EncryptionRequestPacket();

            // Add the game packet handlers
            AddGamePacketHandler(0x00, new SessionPacketHandler(SpecialPacketReceiveHandler));

            // Add the special packet handlers
            AddSpecialPacketHandler(0x02, new SessionPacketHandler(HandleEncryptionResponse));
            AddSpecialPacketHandler(0x05, new SessionPacketHandler(HandleSynchronizeRequest));
            AddSpecialPacketHandler(0x07, new SessionPacketHandler(HandleDisconnect));

            // Log the connection message
            m_sessionLogger(String.Format("Connecting to {0}:{1}",
                                          m_sessionSettings.ServerAddress,
                                          m_sessionSettings.ServerPort));

            // Set the client encryption key value
            packet.EncryptionKey = m_sessionSocket.ClientEncryptKey;

            // Send the packet to the server
            TransmitPacket(packet);
        }
示例#3
0
        private void HandleEncryptionRequest(EncryptionRequestPacket packet)
        {
            var generator = new CipherKeyGenerator();
            generator.Init(new KeyGenerationParameters(new SecureRandom(), 16 * 8));
            var sharedKey = generator.GenerateKey();

            var pkcs = new PKCS1Signer(packet.PublicKey);
            var signedSecret = pkcs.SignData(sharedKey);
            var signedVerify = pkcs.SignData(packet.VerificationToken);

            SendPacketDirect(new EncryptionResponsePacket { SharedSecret = signedSecret, VerificationToken = signedVerify });

            Stream.InitializeEncryption(sharedKey);

            State |= JoinState.JoinedGame;
        }
    /// <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
        });
    }