diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/EncryptionUtil.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/EncryptionUtil.java index 2a6f8439..46c80b0f 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/EncryptionUtil.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/EncryptionUtil.java @@ -3,11 +3,11 @@ package com.github.games647.fastlogin.bukkit.listener.protocollib; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; -import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; import java.security.PublicKey; import java.util.Random; @@ -36,6 +36,7 @@ public class EncryptionUtil { * @return The RSA key pair. */ public static KeyPair generateKeyPair() { + // KeyPair b() try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_PAIR_ALGORITHM); @@ -55,6 +56,7 @@ public class EncryptionUtil { * @return an error with 4 bytes long */ public static byte[] generateVerifyToken(Random random) { + // extracted from LoginListener byte[] token = new byte[VERIFY_TOKEN_LENGTH]; random.nextBytes(token); return token; @@ -68,9 +70,10 @@ public class EncryptionUtil { * @param publicKey public key of the server * @return the server id formatted as a hexadecimal string. */ - public static String getServerIdHashString(String sessionId, Key sharedSecret, PublicKey publicKey) { + public static String getServerIdHashString(String sessionId, SecretKey sharedSecret, PublicKey publicKey) { + // found in LoginListener try { - byte[] serverHash = getServerIdHash(sessionId, sharedSecret, publicKey); + byte[] serverHash = getServerIdHash(sessionId, publicKey, sharedSecret); return (new BigInteger(serverHash)).toString(16); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); @@ -87,8 +90,16 @@ public class EncryptionUtil { * @return shared secret key * @throws GeneralSecurityException if it fails to decrypt the data */ - public static SecretKey decryptSharedKey(Cipher cipher, byte[] sharedKey) throws GeneralSecurityException { - return new SecretKeySpec(decrypt(cipher, sharedKey), "AES"); + public static SecretKey decryptSharedKey(PrivateKey privateKey, byte[] sharedKey) throws GeneralSecurityException { + // SecretKey a(PrivateKey var0, byte[] var1) + return new SecretKeySpec(decrypt(privateKey, sharedKey), "AES"); + } + + public static byte[] decrypt(PrivateKey key, byte[] data) throws GeneralSecurityException { + // b(Key var0, byte[] var1) + Cipher cipher = Cipher.getInstance(key.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, key); + return decrypt(cipher, data); } /** @@ -99,14 +110,17 @@ public class EncryptionUtil { * @return clear text data * @throws GeneralSecurityException if it fails to decrypt the data */ - public static byte[] decrypt(Cipher cipher, byte[] data) throws GeneralSecurityException { + private static byte[] decrypt(Cipher cipher, byte[] data) throws GeneralSecurityException { + // inlined: byte[] a(int var0, Key var1, byte[] var2), Cipher a(int var0, String var1, Key var2) return cipher.doFinal(data); } - private static byte[] getServerIdHash(String sessionId, Key sharedSecret, PublicKey publicKey) + private static byte[] getServerIdHash(String sessionId, PublicKey publicKey, SecretKey sharedSecret) throws NoSuchAlgorithmException { + // byte[] a(String var0, PublicKey var1, SecretKey var2) MessageDigest digest = MessageDigest.getInstance("SHA-1"); + // inlined from byte[] a(String var0, byte[]... var1) digest.update(sessionId.getBytes(StandardCharsets.ISO_8859_1)); digest.update(sharedSecret.getEncoded()); digest.update(publicKey.getEncoded()); diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/VerifyResponseTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/VerifyResponseTask.java index fcb4477e..6ad02bdd 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/VerifyResponseTask.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/VerifyResponseTask.java @@ -26,7 +26,6 @@ import java.util.Arrays; import java.util.Optional; import java.util.UUID; -import javax.crypto.Cipher; import javax.crypto.SecretKey; import org.bukkit.entity.Player; @@ -76,20 +75,16 @@ public class VerifyResponseTask implements Runnable { private void verifyResponse(BukkitLoginSession session) { PrivateKey privateKey = serverKey.getPrivate(); - Cipher cipher; SecretKey loginKey; try { - cipher = Cipher.getInstance(privateKey.getAlgorithm()); - cipher.init(Cipher.DECRYPT_MODE, privateKey); - - loginKey = EncryptionUtil.decryptSharedKey(cipher, sharedSecret); + loginKey = EncryptionUtil.decryptSharedKey(privateKey, sharedSecret); } catch (GeneralSecurityException securityEx) { disconnect("error-kick", false, "Cannot decrypt received contents", securityEx); return; } try { - if (!checkVerifyToken(session, cipher, privateKey) || !encryptConnection(loginKey)) { + if (!checkVerifyToken(session) || !enableEncryption(loginKey)) { return; } } catch (Exception ex) { @@ -141,14 +136,13 @@ public class VerifyResponseTask implements Runnable { } } - private boolean checkVerifyToken(BukkitLoginSession session, Cipher cipher, PrivateKey privateKey) - throws GeneralSecurityException { + private boolean checkVerifyToken(BukkitLoginSession session) throws GeneralSecurityException { byte[] requestVerify = session.getVerifyToken(); //encrypted verify token byte[] responseVerify = packetEvent.getPacket().getByteArrays().read(1); //https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/LoginListener.java#L182 - if (!Arrays.equals(requestVerify, EncryptionUtil.decrypt(cipher, responseVerify))) { + if (!Arrays.equals(requestVerify, EncryptionUtil.decrypt(serverKey.getPrivate(), responseVerify))) { //check if the verify token are equal to the server sent one disconnect("invalid-verify-token", true , "GameProfile {0} ({1}) tried to login with an invalid verify token. Server: {2} Client: {3}" @@ -169,7 +163,7 @@ public class VerifyResponseTask implements Runnable { return FieldUtils.readField(rawInjector, "networkManager", true); } - private boolean encryptConnection(SecretKey loginKey) throws IllegalArgumentException { + private boolean enableEncryption(SecretKey loginKey) throws IllegalArgumentException { try { //get the NMS connection handle of this player Object networkManager = getNetworkManager();