Reputation: 1598
I'm writing a client for Minecraft in Java. I have a lot of things working already, but the one thing that has really stumped me is how Minecraft does its authentication. I found this page
http://wiki.vg/Protocol#Handshake_.280x02.29
Which defines the protocol. As of now, the following code
public boolean connect(String ip, int port) {
try {
socket = new Socket(ip, port);
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
dos.writeByte(0x02);
dos.writeByte(0x00);
writeString(username);
writeString(ip);
dos.writeInt(port);
if (dis.readByte() != 0xFD)
return false;
String serverId = readString();
byte[] publicKey = new byte[dis.readShort()];
for (int i = 0; i < publicKey.length; i++)
publicKey[i] = dis.readByte();
byte[] token = new byte[dis.readShort()];
for (int i = 0; i < token.length; i++)
token[i] = dis.readByte();
PublicKey serverPublicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKey));
byte[] sharedSecret = new byte[16];
new Random().nextBytes(sharedSecret);
URL url = new URL("http://session.minecraft.net/game/joinserver.jsp?user=" + username + "&sessionId=" + session + "&serverId=" + serverId);
url.openConnection();
Cipher cipher = Cipher.getInstance("AES");
return true;
}
catch (Exception ex) { System.out.println("Failed to login for " + username); ex.printStackTrace(); }
return false;
}
is what I have. Through this code, as you can tell, I get a public key, a verification token, and generate a random shared secret. However, I don't know what to do from here. I have seen a Python implementation of this
https://github.com/ammaraskar/pyCraft/blob/master/networking/NetworkManager.py line 82
but I can't figure out how they used SHA1 to grab the serverid. I can't find an equivalent in Java. There is a authentication scheme page specific for Minecraft which more clearly defines what happens in the background here: http://wiki.vg/Protocol_Encryption
Upvotes: 1
Views: 2409
Reputation: 2776
There is an excellent decompilation project for minecraft:
http://mcp.ocean-labs.de/index.php/MCP_Releases.
Have a look in src/minecraft/net/minecraft/src/NetClientHandler.java
, and src/minecraft/net/minecraft/src/ThreadLoginVerifier.java
.
The actual hashing is done in src/minecraft/net/minecraft/src/CryptManager.java
, like this:
digestOperation("SHA-1", new byte[][] {par0Str.getBytes("ISO_8859_1"), par2SecretKey.getEncoded(), par1PublicKey.getEncoded()})
Upvotes: 1