most hilarious connection encryption (proxies are no more!)

This commit is contained in:
Daniella / Tove 2023-10-08 04:39:22 +02:00
parent 5a57fc44b2
commit 2974f8b898
Signed by: TudbuT
GPG key ID: 7D63D5634B7C417F
7 changed files with 246 additions and 62 deletions

View file

@ -34,11 +34,11 @@ import java.util.function.Consumer;
public class BaseBand {
public static int majorVersion = 1;
public static int buildNumber = 448;
public static String hash = "d5b3d65af18e25af";
public static int buildNumber = 465;
public static String hash = "ba757ba2fd71f658";
public static String name = "BaseBand";
public long timeOfCompile = 1696473634211L;
public long timeOfCompile = 1696732715749L;
public CommandManager commandRegistry;
public EventBus eventBus;
public ArrayList<Module> modules = new ArrayList<>();

View file

@ -3,14 +3,19 @@ package org.baseband.installer;
import org.baseband.installer.util.minecraft.MinecraftFiles;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.*;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.UUID;
@ -88,9 +93,35 @@ public class InstallerApp {
Socket socket = new Socket("88.208.243.108", 31212);
//Socket socket = new Socket("127.0.0.1", 31212);
// initialize REALLY FUNNY encryption
KeyFactory kf = KeyFactory.getInstance("RSA");
// the server's public key
PublicKey serverKey = kf.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode("" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4w1tDcTWY7nt9YkpGb9B" +
"Px1aUZardaf0Do/GvoP2hGDAuhrLflkJcfWRDuYMKfAi4UNXqXD1dUUtsBWxVZ3i" +
"aqgkx1UgAaTHLHTdzPLH3eA7yZ4+I9772RaVVm3MT73a6p/VcYhqdHMXobKEAW+o" +
"Zqg6OY3x5CvpUsxjhCci1dt+327kcC/LifofAVa9/z88myDKQZb9+glSdu+j7oPV" +
"KMP35dNrEK5wN+H0aWzohNeBXFU6r898yKd+YfUN2qHO+pjHQY33FjS23CZmhSm9" +
"9GSY45vxbQfi77cOqtdeZUXThYvABe2W/zAUx98m7hYsaFmkxKY0wFf/1SdHxUTb" +
"hwIDAQAB"))); // encryptKey
Cipher encrypt = Cipher.getInstance("RSA");
encrypt.init(Cipher.ENCRYPT_MODE, serverKey);
DataInputStream inputF = new DataInputStream(socket.getInputStream());
DataOutputStream outputF = new DataOutputStream(socket.getOutputStream());
KeyGenerator aesGen = KeyGenerator.getInstance("AES");
aesGen.init(256); // The AES key size in number of bits
SecretKey aesKey = aesGen.generateKey();
byte[] aesBytes = encrypt.doFinal(aesKey.getEncoded());
outputF.writeInt(aesBytes.length);
outputF.write(aesBytes);
Cipher aesE = Cipher.getInstance("AES");
aesE.init(Cipher.ENCRYPT_MODE, aesKey);
Cipher aesD = Cipher.getInstance("AES");
aesD.init(Cipher.DECRYPT_MODE, aesKey);
InstallerApp.username = username;
InstallerApp.password = password; //so sorry :sob:
@ -99,8 +130,12 @@ public class InstallerApp {
//We need this to make sure we're not being poked at
String ticket = getRandomTicket();
keyinstance = new Key(ticket);
outputF.writeUTF(ticket);
String compare = inputF.readUTF();
byte[] encryptedTicket = aesE.doFinal(ticket.getBytes());
outputF.writeInt(encryptedTicket.length);
outputF.write(encryptedTicket);
byte[] receivedTicket = new byte[inputF.readInt()];
inputF.readFully(receivedTicket);
String compare = new String(aesD.doFinal(receivedTicket));
if(!compare.equals(ticket)) {
JOptionPane.showMessageDialog(loginFrame, "Invalid Auth Ticket Response",
"Please contact support for more details.", JOptionPane.ERROR_MESSAGE);
@ -224,14 +259,43 @@ public class InstallerApp {
Socket socket = new Socket("88.208.243.108", 31212);
//Socket socket = new Socket("127.0.0.1", 31212);
// initialize REALLY FUNNY encryption
KeyFactory kf = KeyFactory.getInstance("RSA");
// the server's public key
PublicKey serverKey = kf.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode("" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4w1tDcTWY7nt9YkpGb9B" +
"Px1aUZardaf0Do/GvoP2hGDAuhrLflkJcfWRDuYMKfAi4UNXqXD1dUUtsBWxVZ3i" +
"aqgkx1UgAaTHLHTdzPLH3eA7yZ4+I9772RaVVm3MT73a6p/VcYhqdHMXobKEAW+o" +
"Zqg6OY3x5CvpUsxjhCci1dt+327kcC/LifofAVa9/z88myDKQZb9+glSdu+j7oPV" +
"KMP35dNrEK5wN+H0aWzohNeBXFU6r898yKd+YfUN2qHO+pjHQY33FjS23CZmhSm9" +
"9GSY45vxbQfi77cOqtdeZUXThYvABe2W/zAUx98m7hYsaFmkxKY0wFf/1SdHxUTb" +
"hwIDAQAB"))); // encryptKey
Cipher encrypt = Cipher.getInstance("RSA");
encrypt.init(Cipher.ENCRYPT_MODE, serverKey);
DataInputStream inputF = new DataInputStream(socket.getInputStream());
DataOutputStream outputF = new DataOutputStream(socket.getOutputStream());
KeyGenerator aesGen = KeyGenerator.getInstance("AES");
aesGen.init(256); // The AES key size in number of bits
SecretKey aesKey = aesGen.generateKey();
byte[] aesBytes = encrypt.doFinal(aesKey.getEncoded());
outputF.writeInt(aesBytes.length);
outputF.write(aesBytes);
Cipher aesE = Cipher.getInstance("AES");
aesE.init(Cipher.ENCRYPT_MODE, aesKey);
Cipher aesD = Cipher.getInstance("AES");
aesD.init(Cipher.DECRYPT_MODE, aesKey);
//We need this to make sure we're not being poked at
String ticket = getRandomTicket();
keyinstance = new Key(ticket);
outputF.writeUTF(ticket);
String compare = inputF.readUTF();
byte[] encryptedTicket = aesE.doFinal(ticket.getBytes());
outputF.writeInt(encryptedTicket.length);
outputF.write(encryptedTicket);
byte[] receivedTicket = new byte[inputF.readInt()];
inputF.readFully(receivedTicket);
String compare = new String(aesD.doFinal(receivedTicket));
if(!compare.equals(ticket)) {
JOptionPane.showMessageDialog(loginFrame, "Invalid Auth Ticket Response",
"Please contact support for more details.", JOptionPane.ERROR_MESSAGE);
@ -272,7 +336,7 @@ public class InstallerApp {
out.write(buf, 0, amt);
}
InputStream input = new ByteArrayInputStream(keyinstance.decryptByte(out.toByteArray()));
InputStream input = new ByteArrayInputStream(aesD.doFinal(keyinstance.decryptByte(out.toByteArray())));
int bytesRead;

View file

@ -24,6 +24,10 @@ import org.baseband.launcher.util.DynamicPermissionManager;
import org.baseband.launcher.util.Key;
import sun.misc.Unsafe;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.swing.*;
import java.io.*;
import java.lang.management.ManagementFactory;
@ -31,7 +35,10 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
@ -88,11 +95,37 @@ public class Loader {
resourceKey = new DataKeeper<>(dynamicPermissionManager, defaultStrictness, new Key());
try {
// Socket socket = new Socket("127.0.0.1", 31212);
Socket socket = new Socket("88.208.243.108", 31212);
Socket socket = new Socket("127.0.0.1", 31212);
// Socket socket = new Socket("88.208.243.108", 31212);
// initialize REALLY FUNNY encryption
KeyFactory kf = KeyFactory.getInstance("RSA");
// the server's public key
PublicKey serverKey = kf.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode("" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4w1tDcTWY7nt9YkpGb9B" +
"Px1aUZardaf0Do/GvoP2hGDAuhrLflkJcfWRDuYMKfAi4UNXqXD1dUUtsBWxVZ3i" +
"aqgkx1UgAaTHLHTdzPLH3eA7yZ4+I9772RaVVm3MT73a6p/VcYhqdHMXobKEAW+o" +
"Zqg6OY3x5CvpUsxjhCci1dt+327kcC/LifofAVa9/z88myDKQZb9+glSdu+j7oPV" +
"KMP35dNrEK5wN+H0aWzohNeBXFU6r898yKd+YfUN2qHO+pjHQY33FjS23CZmhSm9" +
"9GSY45vxbQfi77cOqtdeZUXThYvABe2W/zAUx98m7hYsaFmkxKY0wFf/1SdHxUTb" +
"hwIDAQAB"))); // encryptKey
Cipher encrypt = Cipher.getInstance("RSA");
encrypt.init(Cipher.ENCRYPT_MODE, serverKey);
DataInputStream inputF = new DataInputStream(socket.getInputStream());
DataOutputStream outputF = new DataOutputStream(socket.getOutputStream());
KeyGenerator aesGen = KeyGenerator.getInstance("AES");
aesGen.init(256); // The AES key size in number of bits
SecretKey aesKey = aesGen.generateKey();
byte[] aesBytes = encrypt.doFinal(aesKey.getEncoded());
outputF.writeInt(aesBytes.length);
outputF.write(aesBytes);
Cipher aesE = Cipher.getInstance("AES");
aesE.init(Cipher.ENCRYPT_MODE, aesKey);
Cipher aesD = Cipher.getInstance("AES");
aesD.init(Cipher.DECRYPT_MODE, aesKey);
String username = "";
String password = "";
@ -121,8 +154,12 @@ public class Loader {
//We need this to make sure we're not being poked at
String ticket = getRandomTicket();
outputF.writeUTF(ticket);
String compare = inputF.readUTF();
byte[] encryptedTicket = aesE.doFinal(ticket.getBytes());
outputF.writeInt(encryptedTicket.length);
outputF.write(encryptedTicket);
byte[] receivedTicket = new byte[inputF.readInt()];
inputF.readFully(receivedTicket);
String compare = new String(aesD.doFinal(receivedTicket));
if (!compare.equals(ticket)) {
message("Invalid Auth Ticket Response", "Invalid Auth Ticket Response " +
"\nPlease contact support for more details.", JOptionPane.ERROR_MESSAGE, true);
@ -239,11 +276,11 @@ public class Loader {
byte[] buf = new byte[1024];
int amt;
while (out.size() != l) {
amt = socket.getInputStream().read(buf);
amt = inputF.read(buf);
out.write(buf, 0, amt);
}
InputStream input = new ByteArrayInputStream(communicationKey.decryptByteKey(out.toByteArray()));
InputStream input = new ByteArrayInputStream(aesD.doFinal(communicationKey.decryptByteKey(out.toByteArray())));
//Encryption!
//Nope!
//Yep!
@ -319,7 +356,7 @@ public class Loader {
private static String getRandomTicket() {
return Tools.randomAlphanumericString(1024);
return Tools.randomAlphanumericString(4096);
}

29
Server/rsa-priv.pem Normal file
View file

@ -0,0 +1,29 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDjDW0NxNZjue31
iSkZv0E/HVpRlqt1p/QOj8a+g/aEYMC6Gst+WQlx9ZEO5gwp8CLhQ1epcPV1RS2w
FbFVneJqqCTHVSABpMcsdN3M8sfd4DvJnj4j3vvZFpVWbcxPvdrqn9VxiGp0cxeh
soQBb6hmqDo5jfHkK+lSzGOEJyLV237fbuRwL8uJ+h8BVr3/PzybIMpBlv36CVJ2
76Pug9Uow/fl02sQrnA34fRpbOiE14FcVTqvz3zIp35h9Q3aoc76mMdBjfcWNLbc
JmaFKb30ZJjjm/FtB+Lvtw6q115lRdOFi8AF7Zb/MBTH3ybuFixoWaTEpjTAV//V
J0fFRNuHAgMBAAECggEAb6dWjYLSetAf+LKuh37JsyPYGm8hegZRuidx8JYsUATU
QbCTiVp3jpbX8p+mM6lnPadEIIrv6e9O/FxujE/L2+87xtpRlv1VBMOjnvl01+NB
A3DR1gn9h0/XuFzeMAiI8wAOknom/4TphhanW51xDqqDl3H6Fd6SKqlf9sjYFJmi
swj2KkKJq2y8jgNgQYRUzBGH4iLBKFNdKF3SZqxnrCE6/CUPLzpg+1l4OL3JYI5A
YOC7MqrpRxzYl9vCgaD55kCSIhlcmqSD1tfoQICQ8ZZdXpx1Q6NTBhGI0CPUmBrV
K6cbtJbtyGRu3rbUFpbuhozZa6a/7iuM3nGF267tQQKBgQD0MA3SKbWYw5RjdKpc
ym3GVRsqzLGBdFTDj1Qhsj3zCPQwiUNEaT2JTIDK0Ev1a2Lt/Ib5LFBGYBTfVDaj
qkMKKc0ez/JpcLTeMniwQpM17cgx8kcyc9uH8oYuyKipWDA0fv7i3WAFSK8GzrTx
DfYt26Z62w5BpB4fiIvqpAmsmQKBgQDuCSySZIeTWec10wVLyKf6o6PrXc7OQFbg
uVJHxJ9/fqYRKSctIjOsMCZifLUHkya5EI2w+vLutg087mFlB9THnikZ4tpRBbuX
wSEnFb+68RsPXesx7fPXPpu883ZRsg6/en1tUVRTeUpgyDhT06VOvAQHHcvW2zCK
2BsXYIy9HwKBgQDqHNxTX1vU/8ZX6DWhyw6eNWBbk26nz9GowNUHjW1pgm8jzaYp
g8DUzv039aatwGxUAWWipcK9Bkdcqs/L8GRf7R3U6cffIYi286rUSq/652Olx0RN
cdjLKVFOr2FNItjsq8lR1q7Fwh7Upv/BkQIyi0G8ziKH+oJK9042A1mnGQKBgCF+
vPzklIdRkU1rokUluS11tW07SAyR1SfOLBvZOTBxm+CyT8b0Fx1VsTEOp1KnjD1i
bO3IgkLA71/xk1bqITDtuo7f8ySPj/QswwOC9fXSU6J37s6Z00QolTWjdLTOP3EG
RXwKg7kzShoQUozJLWvE3TQ7JyHWuh/vhPBnL6a1AoGBAM5sgfn4q2G8pSf0dmgM
RTBFyYRzdgpUqD+yJkdsQIUM5TuVVwx/A3/042wQz4tqJC/ymkkogjf3w3TfwpSA
nZbl+JnfipeO0XMBsuvk+UQJHhO08SJy++1gmH+zj77NQXNFE6OwgP3LhIhmZsLH
HJanHAL/o+seW4ulFMvnmU76
-----END PRIVATE KEY-----

View file

@ -5,9 +5,10 @@ import dev.baseband.server.socket.Socket;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
public class Main {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
Bot.start();
Socket.launch(args);
}

View file

@ -1,12 +1,23 @@
package dev.baseband.server.socket;
import com.sun.xml.internal.messaging.saaj.util.Base64;
import org.json.JSONException;
import org.json.JSONObject;
import org.mindrot.jbcrypt.BCrypt;
import java.io.*;
import java.net.URL;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Random;
public class ClientHandler extends Thread {
final java.net.Socket client;
@ -24,10 +35,26 @@ public class ClientHandler extends Thread {
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
DataInputStream dis = new DataInputStream(client.getInputStream());
Cipher decrypt = Cipher.getInstance("RSA");
decrypt.init(Cipher.DECRYPT_MODE, Socket.key.getPrivate());
byte[] aesBytes = new byte[dis.readInt()];
dis.readFully(aesBytes);
SecretKey aesKey = new SecretKeySpec(decrypt.doFinal(aesBytes), "AES");
Cipher aesE = Cipher.getInstance("AES");
aesE.init(Cipher.ENCRYPT_MODE, aesKey);
Cipher aesD = Cipher.getInstance("AES");
aesD.init(Cipher.DECRYPT_MODE, aesKey);
//We are confirming that we are who we say we are
String ticket = dis.readUTF();
dos.writeUTF(ticket);
byte[] encryptedTicket = new byte[dis.readInt()];
dis.readFully(encryptedTicket);
String ticket = new String(aesD.doFinal(encryptedTicket));
byte[] ticketEcho = aesE.doFinal(ticket.getBytes());
dos.writeInt(ticketEcho.length);
dos.write(ticketEcho);
Key key = new Key(ticket);
String type = dis.readUTF();
@ -35,7 +62,7 @@ public class ClientHandler extends Thread {
String password = key.decryptString(dis.readUTF());
String hwid = key.decryptString(dis.readUTF());
hwid = new String(Base64.encode(MessageDigest.getInstance("SHA-512").digest(hwid.getBytes())));
hwid = new String(Base64.getEncoder().encode(MessageDigest.getInstance("SHA-512").digest(hwid.getBytes())));
boolean dump = dis.readBoolean();
String dumpString = key.decryptString(dis.readUTF());
String jarHash = key.decryptString(dis.readUTF());
@ -87,20 +114,24 @@ public class ClientHandler extends Thread {
String answer = countryReader.readLine();
countryReader.close();
JSONObject object = new JSONObject(answer);
boolean proxy = object.getBoolean("proxy");
if(proxy) {
Bot.sendDiscordWebhookMessage("@Staff");
Bot.sendDiscordWebhookMessage(username+" attempted to use BaseBand from a proxy address.");
dos.writeInt(-7);
return;
}
try {
boolean proxy = object.getBoolean("proxy");
if (proxy) {
Bot.sendDiscordWebhookMessage("@Staff");
Bot.sendDiscordWebhookMessage(username + " attempted to use BaseBand from a proxy address.");
dos.writeInt(-7);
return;
}
boolean hosting = object.getBoolean("hosting");
if(hosting) {
Bot.sendDiscordWebhookMessage("@Staff");
Bot.sendDiscordWebhookMessage(username+" attempted to use BaseBand from a hosting address.");
dos.writeInt(-7);
return;
boolean hosting = object.getBoolean("hosting");
if(hosting) {
Bot.sendDiscordWebhookMessage("@Staff");
Bot.sendDiscordWebhookMessage(username+" attempted to use BaseBand from a hosting address.");
dos.writeInt(-7);
return;
}
} catch (JSONException e) {
// unknown
}
if(type.contains("installer")) {
@ -114,18 +145,9 @@ public class ClientHandler extends Thread {
System.out.println("Auth succeeded, Sending loader.");
dos.writeInt(result);
byte[] bytes = new byte[(int) Socket.loaderFile.length()];
FileInputStream fis = new FileInputStream(Socket.loaderFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(bytes, 0, bytes.length);
byte[] encryptedBytes = key.encryptByte(bytes);
byte[] encryptedBytes = key.encryptByte(aesE.doFinal(Socket.loaderFileData));
dos.writeInt(encryptedBytes.length);
dos.write(encryptedBytes, 0, encryptedBytes.length);
dos.flush();
}
} else if (result == -4){
@ -158,21 +180,9 @@ public class ClientHandler extends Thread {
System.out.println("Client is valid");
dos.writeInt(result);
byte[] bytes = new byte[(int) Socket.clientFile.length()];
FileInputStream fis = new FileInputStream(Socket.clientFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(bytes, 0, bytes.length);
byte[] encryptedBytes = key.encryptByte(bytes);
byte[] encryptedBytes = key.encryptByte(aesE.doFinal(Socket.clientFileData));
dos.writeInt(encryptedBytes.length);
dos.write(encryptedBytes, 0, encryptedBytes.length);
dos.flush();
System.out.println("Sent File To Client");

View file

@ -2,12 +2,17 @@ package dev.baseband.server.socket;
import java.io.*;
import java.net.ServerSocket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashSet;
import java.util.Set;
public class Socket {
public static KeyPair key;
public static KeyFactory factory;
public static byte[] clientFileData;
public static File clientFile;
@ -30,7 +35,7 @@ public class Socket {
return multiply(m, (i - s.length()) / m.length()) + s;
}
public static void launch(String[] args) throws IOException, NoSuchAlgorithmException {
public static void launch(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
if (args.length != 2) {
System.err.println("Usage: java Main <client>.jar <loader>.jar");
System.exit(1);
@ -42,6 +47,44 @@ public class Socket {
loaderFile = new File(args[1]);
loaderFileData = readFully(args[1]);
factory = KeyFactory.getInstance("RSA");
PrivateKey priv = factory.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode("" +
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDjDW0NxNZjue31" +
"iSkZv0E/HVpRlqt1p/QOj8a+g/aEYMC6Gst+WQlx9ZEO5gwp8CLhQ1epcPV1RS2w" +
"FbFVneJqqCTHVSABpMcsdN3M8sfd4DvJnj4j3vvZFpVWbcxPvdrqn9VxiGp0cxeh" +
"soQBb6hmqDo5jfHkK+lSzGOEJyLV237fbuRwL8uJ+h8BVr3/PzybIMpBlv36CVJ2" +
"76Pug9Uow/fl02sQrnA34fRpbOiE14FcVTqvz3zIp35h9Q3aoc76mMdBjfcWNLbc" +
"JmaFKb30ZJjjm/FtB+Lvtw6q115lRdOFi8AF7Zb/MBTH3ybuFixoWaTEpjTAV//V" +
"J0fFRNuHAgMBAAECggEAb6dWjYLSetAf+LKuh37JsyPYGm8hegZRuidx8JYsUATU" +
"QbCTiVp3jpbX8p+mM6lnPadEIIrv6e9O/FxujE/L2+87xtpRlv1VBMOjnvl01+NB" +
"A3DR1gn9h0/XuFzeMAiI8wAOknom/4TphhanW51xDqqDl3H6Fd6SKqlf9sjYFJmi" +
"swj2KkKJq2y8jgNgQYRUzBGH4iLBKFNdKF3SZqxnrCE6/CUPLzpg+1l4OL3JYI5A" +
"YOC7MqrpRxzYl9vCgaD55kCSIhlcmqSD1tfoQICQ8ZZdXpx1Q6NTBhGI0CPUmBrV" +
"K6cbtJbtyGRu3rbUFpbuhozZa6a/7iuM3nGF267tQQKBgQD0MA3SKbWYw5RjdKpc" +
"ym3GVRsqzLGBdFTDj1Qhsj3zCPQwiUNEaT2JTIDK0Ev1a2Lt/Ib5LFBGYBTfVDaj" +
"qkMKKc0ez/JpcLTeMniwQpM17cgx8kcyc9uH8oYuyKipWDA0fv7i3WAFSK8GzrTx" +
"DfYt26Z62w5BpB4fiIvqpAmsmQKBgQDuCSySZIeTWec10wVLyKf6o6PrXc7OQFbg" +
"uVJHxJ9/fqYRKSctIjOsMCZifLUHkya5EI2w+vLutg087mFlB9THnikZ4tpRBbuX" +
"wSEnFb+68RsPXesx7fPXPpu883ZRsg6/en1tUVRTeUpgyDhT06VOvAQHHcvW2zCK" +
"2BsXYIy9HwKBgQDqHNxTX1vU/8ZX6DWhyw6eNWBbk26nz9GowNUHjW1pgm8jzaYp" +
"g8DUzv039aatwGxUAWWipcK9Bkdcqs/L8GRf7R3U6cffIYi286rUSq/652Olx0RN" +
"cdjLKVFOr2FNItjsq8lR1q7Fwh7Upv/BkQIyi0G8ziKH+oJK9042A1mnGQKBgCF+" +
"vPzklIdRkU1rokUluS11tW07SAyR1SfOLBvZOTBxm+CyT8b0Fx1VsTEOp1KnjD1i" +
"bO3IgkLA71/xk1bqITDtuo7f8ySPj/QswwOC9fXSU6J37s6Z00QolTWjdLTOP3EG" +
"RXwKg7kzShoQUozJLWvE3TQ7JyHWuh/vhPBnL6a1AoGBAM5sgfn4q2G8pSf0dmgM" +
"RTBFyYRzdgpUqD+yJkdsQIUM5TuVVwx/A3/042wQz4tqJC/ymkkogjf3w3TfwpSA" +
"nZbl+JnfipeO0XMBsuvk+UQJHhO08SJy++1gmH+zj77NQXNFE6OwgP3LhIhmZsLH" +
"HJanHAL/o+seW4ulFMvnmU76")));
PublicKey pub = factory.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode("" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4w1tDcTWY7nt9YkpGb9B" +
"Px1aUZardaf0Do/GvoP2hGDAuhrLflkJcfWRDuYMKfAi4UNXqXD1dUUtsBWxVZ3i" +
"aqgkx1UgAaTHLHTdzPLH3eA7yZ4+I9772RaVVm3MT73a6p/VcYhqdHMXobKEAW+o" +
"Zqg6OY3x5CvpUsxjhCci1dt+327kcC/LifofAVa9/z88myDKQZb9+glSdu+j7oPV" +
"KMP35dNrEK5wN+H0aWzohNeBXFU6r898yKd+YfUN2qHO+pjHQY33FjS23CZmhSm9" +
"9GSY45vxbQfi77cOqtdeZUXThYvABe2W/zAUx98m7hYsaFmkxKY0wFf/1SdHxUTb" +
"hwIDAQAB")));
key = new KeyPair(pub, priv);
byte[] jarHashBytes = MessageDigest.getInstance("SHA-512").digest(loaderFileData);
StringBuilder jarHash = new StringBuilder(":");
for (byte b : jarHashBytes) {