From 7e3ed3e5ca248434b61e876df227ec4ea72b46a2 Mon Sep 17 00:00:00 2001 From: Aaron <51387595+AzureAaron@users.noreply.github.com> Date: Sat, 22 Jun 2024 00:37:58 -0400 Subject: Add documentation --- .../de/hysky/skyblocker/utils/ApiAuthentication.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java') diff --git a/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java b/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java index 6a6f388f..fbf814ee 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.text.Text; 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 class ApiAuthentication { 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 @@ public class ApiAuthentication { }); } + /** + * 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); -- cgit