aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java
blob: 9fc16054dd2d271d2ca35560f17409a5debd39db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package kr.syeyoung.dungeonsguide;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import lombok.Getter;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Session;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.*;
import java.security.*;
import java.util.UUID;

public class Authenticator {
    @Getter
    private KeyPair keyPair;
    @Getter
    private String token;
    private KeyPair generate1024RSAKey()  {
        KeyPairGenerator generator = null;
        try {
            generator = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        generator.initialize(1024);
        keyPair = generator.generateKeyPair();
        return  keyPair;
    }

    public Authenticator() {
        generate1024RSAKey();
    }

    private static final String DOMAIN = "http://localhost:8080/";

    public String authenticate() throws IOException, AuthenticationException, NoSuchAlgorithmException {
        Session session = Minecraft.getMinecraft().getSession();
        String token = session.getToken();

        String jwt = requestAuth(session.getProfile());
        MinecraftSessionService yggdrasilMinecraftSessionService = Minecraft.getMinecraft().getSessionService();
        JsonObject jwt2 = parseJWT(jwt);
        String hash = calculateAuthHash(DatatypeConverter.parseBase64Binary(jwt2.get("sharedSecret").getAsString()),
                DatatypeConverter.parseBase64Binary(jwt2.get("publicKey").getAsString()));
        yggdrasilMinecraftSessionService.joinServer(session.getProfile(), token, hash);
        this.token = requestAuth2(jwt, keyPair.getPublic());
        return this.token;
    }

    public JsonObject parseJWT(String jwt) {
        String payload = jwt.split("\\.")[1].replace("+", "-").replace("/", "_");
        String json = new String(DatatypeConverter.parseBase64Binary(payload));
        return (JsonObject) new JsonParser().parse(json);
    }

    private String requestAuth(GameProfile profile) throws IOException {
        HttpURLConnection huc = (HttpURLConnection) new URL(DOMAIN+"auth/requestAuth").openConnection();
        huc.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
        huc.setRequestProperty("Content-Type", "application/json");
        huc.setRequestMethod("POST");
        huc.setDoInput(true);
        huc.setDoOutput(true);

        huc.getOutputStream().write(("{\"uuid\":\""+profile.getId().toString()+"\",\"nickname\":\""+profile.getName()+"\"}").getBytes());
        InputStreamReader inputStreamReader = new InputStreamReader(huc.getInputStream());
        JsonObject object = (JsonObject) new JsonParser().parse(inputStreamReader);
        if (!"ok".equals(object.get("status").getAsString())) {
            return null;
        }
        return object.get("data").getAsString();
    }
    private String requestAuth2(String token, PublicKey publicKey) throws IOException {
        HttpURLConnection huc = (HttpURLConnection) new URL(DOMAIN+"auth/authenticate").openConnection();
        huc.setRequestMethod("POST");
        huc.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
        huc.setRequestProperty("Content-Type", "application/json");
        huc.setDoInput(true);
        huc.setDoOutput(true);

        huc.getOutputStream().write(("{\"jwt\":\""+token+"\",\"publicKey\":\""+DatatypeConverter.printBase64Binary(publicKey.getEncoded())+"\"}").getBytes());
        InputStreamReader inputStreamReader = new InputStreamReader(huc.getInputStream());
        JsonObject object = (JsonObject) new JsonParser().parse(inputStreamReader);
        if (!"ok".equals(object.get("status").getAsString())) {
            return null;
        }
        return object.get("data").getAsString();
    }
    public String calculateAuthHash(byte[] sharedSecret, byte[] pk) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update("".getBytes());
        md.update(sharedSecret);
        md.update(pk);
        byte[] result = md.digest();
        return new BigInteger(result).toString(16);
    }
}