Skip to content
Advertisement

Minecraft Client Server Login Protocol – Malformed public key bytes

I was able to get the server list ping to work fine but when I moved on to the login protocol, I’m having some issues.

After some analysis with Wireshark it looks like its sending the handshake and login packets in the same packet. I’m starting off with a offline login. Fom what I understand from the Wiki, if you set hasSigData to false you don’t need to send a public key and all that stuff. All I’m sending over is the username, hasSigData as false, and hasPlayerUUID as true with a UUID v3 derived from the string OfflinePlayer:[username].

I have two questions:

  1. Am I even encoding the login packet right. Yes the server I’m trying to log in to is in offline mode.
  2. How do I separate the packets?

Packet Hex dump from wireshark

I have marked out where the data starts and roughly where the handshake packet ends and the login packet begins.

Server response

/[My IP] lost connection: Internal Exception: io.netty.handler.codec.DecoderException: Malformed public key bytes

My code

LoginStart Packet (Offlne)

public static byte[] getLoginStartPacket(String name) throws IOException {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    DataOutputStream loginStart = new DataOutputStream(buffer);

    UUID uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8));

    loginStart.writeByte(PACKET_ID);
    loginStart.writeChars(name);
    loginStart.writeBoolean(false);
    loginStart.writeBoolean(true);
    MinecraftUUID.writeBytes(loginStart, uuid);

    return buffer.toByteArray();
}

Sending Packet

    byte[] handshakeMessage = Handshake.getHandshakePacket(
                this.port,
                this.serverAddress,
                this.protocolVersion,
                2);

    VarInt.write(dataOutputStream, handshakeMessage.length);
    dataOutputStream.write(handshakeMessage);

    byte[] login = LoginOfflineStart.getLoginStartPacket(name);
    VarInt.write(dataOutputStream, login.length);
    dataOutputStream.write(login);

Advertisement

Answer

Hey i figured it out when you send the username you need to add a byte before it to indicate the length of the username this as probably in the wiki sorry about that

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement