diff --git a/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java b/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java index 6a6f388f42..fbf814ee1d 100644 --- a/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java +++ b/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java @@ -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(); @@ -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 -> { @@ -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);