diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JAConfigurator.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JAConfigurator.java index 5166b659..adbb3cb8 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JAConfigurator.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JAConfigurator.java @@ -72,6 +72,12 @@ public void setProjectName(String name) { body.append("\";"); } + public void setSecretKey(String key) { + body.append("this.secretKeyClient = \""); + body.append(key); + body.append("\";"); + } + public void setPort(int port) { body.append("this.port = "); body.append(port); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java index 3dc39944..051db9c1 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java @@ -165,6 +165,7 @@ private void stdBuild() throws IOException { jaConfigurator.setAddress(server.config.getAddress()); jaConfigurator.setPort(server.config.port); jaConfigurator.setProjectName(server.config.projectName); + jaConfigurator.setSecretKey(SecurityHelper.randomStringToken()); server.buildHookManager.registerAllClientModuleClass(jaConfigurator); try (ZipInputStream input = new ZipInputStream( IOHelper.newInput(IOHelper.getResourceURL("Launcher.jar")))) { diff --git a/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java b/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java index 8a0e24c7..df2100a1 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java +++ b/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java @@ -109,7 +109,7 @@ public Params(byte[] launcherSign, Path assetDir, Path clientDir, PlayerProfile } @LauncherAPI - public Params(HInput input) throws IOException { + public Params(HInput input) throws Exception { launcherSign = input.readByteArray(-SecurityHelper.RSA_KEY_LENGTH); // Client paths assetDir = IOHelper.toPath(input.readString(0)); @@ -122,7 +122,9 @@ public Params(HInput input) throws IOException { } // Client params pp = new PlayerProfile(input); - accessToken = SecurityHelper.verifyToken(input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH)); + byte[] encryptedAccessToken = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH); + String accessTokenD = new String(SecurityHelper.decrypt(Launcher.getConfig().secretKeyClient.getBytes(),encryptedAccessToken)); + accessToken = SecurityHelper.verifyToken(accessTokenD); autoEnter = input.readBoolean(); fullScreen = input.readBoolean(); ram = input.readVarInt(); @@ -143,7 +145,11 @@ public void write(HOutput output) throws IOException { } // Client params pp.write(output); - output.writeASCII(accessToken, -SecurityHelper.TOKEN_STRING_LENGTH); + try { + output.writeByteArray(SecurityHelper.encrypt(Launcher.getConfig().secretKeyClient.getBytes(),accessToken.getBytes()), SecurityHelper.CRYPTO_MAX_LENGTH); + } catch (Exception e) { + LogHelper.error(e); + } output.writeBoolean(autoEnter); output.writeBoolean(fullScreen); output.writeVarInt(ram); diff --git a/libLauncher/src/main/java/ru/gravit/launcher/AutogenConfig.java b/libLauncher/src/main/java/ru/gravit/launcher/AutogenConfig.java index f7a9ce8e..32f6b445 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/AutogenConfig.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/AutogenConfig.java @@ -5,6 +5,7 @@ public class AutogenConfig { public String address; public int port; private boolean isInitModules; + public String secretKeyClient; AutogenConfig() { diff --git a/libLauncher/src/main/java/ru/gravit/launcher/LauncherConfig.java b/libLauncher/src/main/java/ru/gravit/launcher/LauncherConfig.java index 070d1253..a06eaed4 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/LauncherConfig.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/LauncherConfig.java @@ -34,6 +34,7 @@ public static AutogenConfig getAutogenConfig() { public final InetSocketAddress address; @LauncherAPI public final String projectname; + public String secretKeyClient; @LauncherAPI public final RSAPublicKey publicKey; @@ -47,6 +48,7 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException ADDRESS_OVERRIDE == null ? localAddress : ADDRESS_OVERRIDE, config.port); publicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH)); projectname = config.projectname; + secretKeyClient = config.secretKeyClient; // Read signed runtime int count = input.readLength(0); Map localResources = new HashMap<>(count); diff --git a/libLauncher/src/main/java/ru/gravit/utils/helper/SecurityHelper.java b/libLauncher/src/main/java/ru/gravit/utils/helper/SecurityHelper.java index b7ff252c..774e7478 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/helper/SecurityHelper.java +++ b/libLauncher/src/main/java/ru/gravit/utils/helper/SecurityHelper.java @@ -1,5 +1,6 @@ package ru.gravit.utils.helper; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -25,7 +26,10 @@ import java.util.Random; import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; import ru.gravit.launcher.LauncherAPI; @@ -97,6 +101,7 @@ public byte[] verify(byte[] digest) { // Certificate constants @LauncherAPI public static final String HEX = "0123456789abcdef"; + public static final byte[] NUMBERS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; @LauncherAPI public static final SecureRandom secureRandom = new SecureRandom(); @@ -463,4 +468,46 @@ public static String verifyToken(String token) { private SecurityHelper() { } + //AES + public static byte[] encrypt(String seed, byte[] cleartext) throws Exception { + byte[] rawKey = getRawKey(seed.getBytes()); + byte[] result = encrypt(rawKey, cleartext); + return result; + } + + public static byte[] encrypt(String seed, String cleartext) throws Exception { + return encrypt(seed, cleartext.getBytes()); + } + + private static byte[] getRawKey(byte[] seed) throws Exception { + KeyGenerator kGen = KeyGenerator.getInstance("AES"); + SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); + sr.setSeed(seed); + kGen.init(128, sr); // 192 and 256 bits may not be available + SecretKey sKey = kGen.generateKey(); + return sKey.getEncoded(); + } + + + public static byte[] encrypt(byte[] raw, byte[] clear) throws Exception { + SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES"); + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); + return cipher.doFinal(clear); + } + + public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception { + SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES"); + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, sKeySpec); + return cipher.doFinal(encrypted); + } + public static byte[] HexToByte(String hexString) { + int len = hexString.length() / 2; + byte[] result = new byte[len]; + for (int i = 0; i < len; i++) { + result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue(); + } + return result; + } }