diff options
author | syeyoung <42869671+cyoung06@users.noreply.github.com> | 2020-12-08 14:54:17 +0900 |
---|---|---|
committer | syeyoung <42869671+cyoung06@users.noreply.github.com> | 2020-12-08 14:54:17 +0900 |
commit | 87e89fd42ca44400a3d3d3d5477cd1525b24d91a (patch) | |
tree | 02023a2650c2a9e4fd2d47f64cb91ec614a28556 /src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java | |
parent | 055520e1d8313a302f58babc6526d95bf22b471f (diff) | |
download | Skyblock-Dungeons-Guide-87e89fd42ca44400a3d3d3d5477cd1525b24d91a.tar.gz Skyblock-Dungeons-Guide-87e89fd42ca44400a3d3d3d5477cd1525b24d91a.tar.bz2 Skyblock-Dungeons-Guide-87e89fd42ca44400a3d3d3d5477cd1525b24d91a.zip |
authentication stuff and network loading
Diffstat (limited to 'src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java')
-rw-r--r-- | src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java b/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java new file mode 100644 index 00000000..15b238c6 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java @@ -0,0 +1,133 @@ +package kr.syeyoung.dungeonsguide; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.interfaces.DecodedJWT; +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(); + DecodedJWT jwt2 = JWT.decode(jwt); + String hash = calculateAuthHash(DatatypeConverter.parseBase64Binary(jwt2.getClaim("sharedSecret").asString()), + DatatypeConverter.parseBase64Binary(jwt2.getClaim("publicKey").asString())); + yggdrasilMinecraftSessionService.joinServer(session.getProfile(), token, hash); + token = requestAuth2(jwt, keyPair.getPublic()); + return token; + } + + 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); + } + public InputStream getInputStream(String resource) throws IOException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException { + HttpURLConnection huc = (HttpURLConnection) new URL(DOMAIN+"resource/resource?class="+ URLEncoder.encode(resource)).openConnection(); + huc.setRequestProperty("User-Agent", "DungeonsGuide/1.0"); + huc.setRequestProperty("Content-Type", "application/json"); + huc.setRequestProperty("Authorization", token); + huc.setDoInput(true); + huc.setDoOutput(true); + + InputStream inputStream = huc.getInputStream(); + byte[] bytes = new byte[4]; + inputStream.read(bytes); + int len = ((bytes[0] & 0xFF) << 24) | + ((bytes[1] & 0xFF) << 16) | + ((bytes[2] & 0xFF) << 8 ) | + ((bytes[3] & 0xFF)); + + byte[] pubKey = new byte[len]; + inputStream.read(pubKey); + + Cipher cipher = Cipher.getInstance("RSA"); + byte[] byteEncrypted = pubKey; + cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); + byte[] bytePlain = cipher.doFinal(byteEncrypted); + + cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec keySpec = new SecretKeySpec(bytePlain, "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(bytePlain); + cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec); + return new CipherInputStream(inputStream, cipher); + } +} |