Skip to content

Commit

Permalink
Add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
AzureAaron committed Jun 22, 2024
1 parent 6fbe98c commit 7e3ed3e
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
import net.minecraft.util.Uuids;
import net.minecraft.util.dynamic.Codecs;

/**
* This class is responsible for communicating with the API to retrieve a fully custom token used to gain access to more privileged APIs
* such as the Hypixel API Proxy. The main point of this is to verify that a person is most likely playing Minecraft, and thus is likely to be
* using the mod, and not somebody who is attempting to freeload off of our services.
*/
public class ApiAuthentication {
private static final Logger LOGGER = LogUtils.getLogger();
private static final MinecraftClient CLIENT = MinecraftClient.getInstance();
Expand All @@ -41,6 +46,15 @@ public static void init() {
ClientLifecycleEvents.CLIENT_STARTED.register(_client -> updateToken());
}

/**
* Refreshes the token by fetching the player's key pair from the Minecraft Services API.
*
* We use the player's uuid, public key, public key signature, public key expiry date, and randomly signed data by the private key to verify the identity/legitimacy
* of the player without the server needing to handle any privileged information.
*
* Mojang provides a signature for each key pair which is comprised of the player's uuid, public key, and expiry time so we can easily validate if the key pair
* was generated by Mojang and is tied to said player. For information about what the randomly signed data is used for and why see {@link #getRandomSignedData(PrivateKey)}
*/
private static void updateToken() {
//The fetching runs async in ProfileKeysImpl#getKeyPair
CLIENT.getProfileKeys().fetchKeyPair().thenAcceptAsync(playerKeypairOpt -> {
Expand Down Expand Up @@ -79,6 +93,12 @@ private static void updateToken() {
});
}

/**
* Signs a string of random data with the key pair's private key. This is required to know if you are the real holder of the key pair or not. Why? Because your public key,
* public key signature, and expiry time are forwarded by the server to all players on the same server as you. This means that a malicious
* individual could scrape key pairs and pretend to be someone else when requesting a token from our API. So by signing data with the private key,
* the server can use the public key to verify its integrity which proves that the requester is the true holder of the complete key pair and not someone trying to pose as them for malicious purposes.
*/
private static TokenRequest.SignedData getRandomSignedData(PrivateKey privateKey) {
try {
Signature signature = Signature.getInstance(ALGORITHM);
Expand Down

0 comments on commit 7e3ed3e

Please sign in to comment.