Authentication - AlignedCookie88/FireClient GitHub Wiki

FireClient Authentication allows programs connected through the API to authenticate the player through mojang's authentication services.

It works mostly the same as regular Minecraft Server authentication, but doesn't use a serverId, and uses a regular hexdigest on the sha1 hash.

Error handling

When authenticating, it is fairly common for errors to arise. You should always check the success attribute on the response, and handle errors appropriately when needed.

There could be many reasons why an error is thrown, including but not limited to:

  • The user is playing with a cracked account
  • The user's session token has expired
  • The user has disabled authentication via the config

FireClient will return an error of type com.alignedcookie88.fireclient.api.packet.DoAuthPacket$AuthDisabledException when authentication has been disabled in the config.

Example usage (Python)

Please note that the below script requires the following libraries

  • cryptography
  • websocket-client
import json
import base64
import requests
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from websocket import create_connection
from hashlib import sha1

# Generate the keypair, always do this at the start of your program, as it can take a while on slower computers.

print("Generating keypair")


private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=1024,
    backend=default_backend()
)
public_key = private_key.public_key()

public_der = public_key.public_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)


# Connect to the FireClient API

ws = create_connection("ws://localhost:39870")


# Receive the welcome message

d = ws.recv()
print(d)


# Set the identity of the program (not strictly required, but the name is shown on screen, if you don't do this it will show the API connection ID instead)

print("Setting identity")

ws.send(json.dumps({
    "type": "identify",
    "data": {
        "name": "Authentication Example"
    }
}))

d = ws.recv()
print(d)


# Request the client to log in with mojang's authentication servers, providing it your public key.

print("Logging in")

ws.send(json.dumps({
    "type": "do_auth",
    "data": {
        "publicKey": base64.b64encode(public_der).decode("utf-8")
    }
}))

d = ws.recv()
print(d)


# Close the connection to the FireClient API

ws.close()

# Extract the response data

response = json.loads(d)["response"]
username = response["username"]

secretKeyEncrypted = base64.b64decode(response["secretKey"])


# Decrypt the secret key using your private key, note the padding used.

secretKey = private_key.decrypt(secretKeyEncrypted, padding.PKCS1v15())


# Create the server hash in the same way FireClient did, note this is different to the way Minecraft does it as it uses a regular hexdigest on the hash.

serverHash = sha1(secretKey + public_der).hexdigest()[0:30]


# Send a request to the authentication servers, if you get back a sucessfull response the player has logged in successfully.

r = requests.get("https://sessionserver.mojang.com/session/minecraft/hasJoined?username="+username+"&serverId="+serverHash)

print(r.json())