Initial Commit

This commit is contained in:
Vulpovile
2025-11-14 09:41:07 -08:00
commit 6f88304783
7 changed files with 2748 additions and 0 deletions

6
.classpath Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="output" path="bin"/>
</classpath>

60
.gitignore vendored Normal file
View File

@@ -0,0 +1,60 @@
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
.apt_generated_tests/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project

17
.project Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>KeyGenerator</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,236 @@
package com.legacyroblox.authtool;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class KeyPairGeneratorDialog extends JDialog {
private static final long serialVersionUID = 1L;
private final JPanel contentPanel = new JPanel();
private File outputFile = null;
JComboBox comboBox = new JComboBox();
private JTextField textField;
JTextArea textArea = new JTextArea();
Set<String> supported = new HashSet<String>(Arrays.asList(new String[] { "RSA" }));
private JComboBox cmbSize;
/**
* Create the dialog.
* @param mainInterface
*/
public KeyPairGeneratorDialog(final MainInterface mainInterface) {
super(mainInterface, "Keypair Generator");
setResizable(false);
Set<String> algorithms = new TreeSet<String>();
for (Provider provider : Security.getProviders()) {
for (Provider.Service service : provider.getServices()) {
if ("KeyPairGenerator".equalsIgnoreCase(service.getType()) && supported.contains(service.getAlgorithm())) {
algorithms.add(service.getAlgorithm());
}
}
}
setSize(443, 364);
setLocationRelativeTo(mainInterface);
getContentPane().setLayout(new BorderLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
contentPanel.setLayout(null);
{
JLabel lblType = new JLabel("Type:");
lblType.setBounds(12, 12, 45, 17);
contentPanel.add(lblType);
}
comboBox.setModel(new DefaultComboBoxModel(algorithms.toArray()));
comboBox.setBounds(62, 7, 199, 26);
contentPanel.add(comboBox);
JLabel lblPublicKey = new JLabel("Public Key:");
lblPublicKey.setBounds(12, 41, 123, 17);
contentPanel.add(lblPublicKey);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(12, 70, 416, 151);
contentPanel.add(scrollPane);
scrollPane.setViewportView(textArea);
JButton btnGenerate = new JButton("Generate");
btnGenerate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
generateKeypair();
}
});
btnGenerate.setBounds(323, 233, 105, 27);
contentPanel.add(btnGenerate);
textField = new JTextField();
textField.setEditable(false);
textField.setBounds(90, 236, 221, 21);
contentPanel.add(textField);
textField.setColumns(10);
JButton btnFile = new JButton("File");
btnFile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showSaveDialog(KeyPairGeneratorDialog.this);
if(result == JFileChooser.APPROVE_OPTION) {
outputFile = fileChooser.getSelectedFile();
textField.setText(outputFile.getPath());
}
}
});
btnFile.setBounds(12, 233, 70, 27);
contentPanel.add(btnFile);
JLabel lblSize = new JLabel("Size:");
lblSize.setBounds(279, 12, 38, 17);
contentPanel.add(lblSize);
cmbSize = new JComboBox(new DefaultComboBoxModel(new Integer[]{
1024,
2048,
4096,
8192,
16384
}));
cmbSize.setSelectedIndex(2);
cmbSize.setBounds(323, 7, 105, 26);
contentPanel.add(cmbSize);
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
JButton btnUse = new JButton("Use");
btnUse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(outputFile != null && outputFile.exists() && outputFile.isFile()) {
if(mainInterface.setKeyFile(outputFile, KeyPairGeneratorDialog.this)) {
dispose();
}
}
else {
JOptionPane.showMessageDialog(KeyPairGeneratorDialog.this, "No key exists to use.");
}
}
});
btnUse.setActionCommand("OK");
buttonPane.add(btnUse);
{
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
}
}
}
public String formatKey(Key key) {
StringBuilder pemBuilder = new StringBuilder();
String type = (key instanceof PrivateKey) ? "PRIVATE" : "PUBLIC";
pemBuilder.append("-----BEGIN ").append(type).append(" KEY-----").append(System.getProperty("line.separator"));
String encoded = Base64.encodeBytes(key.getEncoded());
while(encoded.length() > 64) {
pemBuilder.append(encoded.substring(0, 64)).append(System.getProperty("line.separator"));
encoded = encoded.substring(64);
}
pemBuilder.append(encoded).append(System.getProperty("line.separator"));
pemBuilder.append("-----END ").append(type).append(" KEY-----").append(System.getProperty("line.separator"));
return pemBuilder.toString();
}
public void generateKeypair() {
if(outputFile == null) {
JOptionPane.showMessageDialog(this, "You must select an output file.");
return;
}
BufferedWriter bw = null;
try {
String kp = String.valueOf(comboBox.getSelectedItem());
KeyPairGenerator kpg = KeyPairGenerator.getInstance(kp);
if(kp == "RSA") {
int size = ((Integer)cmbSize.getSelectedItem()).intValue();
if(size > 8192 && JOptionPane.showConfirmDialog(this, "This key size is gigantic! It will take ages to create. Are you sure?") != JOptionPane.YES_OPTION) {
return;
}
kpg.initialize(size);
}
KeyPair keyPair = kpg.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String pubKey = formatKey(publicKey);
String privKey = formatKey(privateKey);
File outputPub = new File(outputFile.getAbsolutePath() + ".pub");
bw = new BufferedWriter(new FileWriter(outputFile));
bw.write(privKey);
bw.close();
bw = new BufferedWriter(new FileWriter(outputPub));
bw.write(pubKey);
textArea.setText(pubKey);
}
catch (NoSuchAlgorithmException e) {
textArea.setText("Failed: " + e);
}
catch (IOException e) {
textArea.setText("Failed: " + e);
}
finally {
if(bw != null) {
try {
bw.close();
}
catch (IOException e) {
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
package com.legacyroblox.authtool;
public enum KeyType {
RSA(1),
Ed25519(2);
private KeyType(int id) {
this.id = id;
}
public String getElement() {
return this.toString();
}
public final int id;
}

View File

@@ -0,0 +1,348 @@
package com.legacyroblox.authtool;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Properties;
import java.util.zip.CRC32;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class MainInterface extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField textField;
private File keyFile;
private PrivateKey pk;
JTextArea textArea = new JTextArea();
JTextArea textArea_1 = new JTextArea();
File propFile = new File("LGCYRBXA.PRP");
Properties properties = new Properties();
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainInterface frame = new MainInterface();
frame.setVisible(true);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void loadProperties() {
FileInputStream fos = null;
try {
fos = new FileInputStream(propFile);
properties.load(fos);
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if(fos != null) {
try {
fos.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
String f = properties.getProperty("key-file", null);
if(f == null) {
this.keyFile = null;
this.textArea.setText("");
return;
}
this.setKeyFile(new File(f), this);
}
public void storeProperties() {
if(this.keyFile == null)
properties.remove("key-file");
else
properties.setProperty("key-file", keyFile.getPath());
FileOutputStream fos = null;
try {
fos = new FileOutputStream(propFile);
properties.store(fos, "Authenticator Properties");
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if(fos != null) {
try {
fos.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void toBytes(long value, byte[] dest, int offset) {
dest[offset] = (byte) ((value >>> 24) & 0xFF);
dest[offset+1] = (byte) ((value >>> 16) & 0xFF);
dest[offset+2] = (byte) ((value >>> 8) & 0xFF);
dest[offset+3] = (byte) (value & 0xFF);
}
public static Long crcKey(File file) {
byte[] keyBytes = readKeyBytes(file);
if(keyBytes == null)
return null;
CRC32 crc = new CRC32();
crc.update(keyBytes);
return crc.getValue();
}
/**
* Create the frame.
*/
public MainInterface() {
super("LegacyRoblox.com Authentication Utility v1.0");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(450, 378);
setLocationRelativeTo(null);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblCertificateFile = new JLabel("Private Key:");
lblCertificateFile.setBounds(12, 12, 76, 17);
contentPane.add(lblCertificateFile);
JLabel lblBlob = new JLabel("BLOB:");
lblBlob.setBounds(12, 41, 105, 17);
contentPane.add(lblBlob);
JLabel lblResult = new JLabel("Result:");
lblResult.setBounds(12, 165, 105, 17);
contentPane.add(lblResult);
JButton btnNewButton = new JButton("Done");
btnNewButton.setBounds(325, 290, 105, 27);
contentPane.add(btnNewButton);
textField = new JTextField();
textField.setBounds(100, 7, 242, 26);
contentPane.add(textField);
textField.setEditable(false);
textField.setColumns(10);
JButton btnSelect = new JButton("Select");
btnSelect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
int i = fileChooser.showOpenDialog(MainInterface.this);
if (i == JFileChooser.APPROVE_OPTION) {
setKeyFile(fileChooser.getSelectedFile(), MainInterface.this);
}
}
});
btnSelect.setBounds(354, 7, 76, 27);
contentPane.add(btnSelect);
JButton btnGe = new JButton("Get Result");
btnGe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (pk == null) {
textArea_1.setText("No valid key selected.");
}
else {
try {
byte[] data = Base64.decode(textArea.getText().trim());
Cipher encrypt=Cipher.getInstance("RSA");
encrypt.init(Cipher.ENCRYPT_MODE, pk);
byte[] encryptedMessage=encrypt.doFinal(data);
byte[] fullMessage = new byte[encryptedMessage.length + 8];
Long keyCrc = crcKey(new File(keyFile.getAbsolutePath() + ".pub"));
if(keyCrc != null) {
toBytes(keyCrc, fullMessage, 0);
toBytes(KeyType.RSA.id, fullMessage, 4);
System.arraycopy(encryptedMessage, 0, fullMessage, 8, encryptedMessage.length);
textArea_1.setText(Base64.encodeBytes(fullMessage));
}
else {
textArea_1.setText("Public key not found or invalid");
}
}
catch (IllegalArgumentException e1) {
e1.printStackTrace();
textArea_1.setText("Invalid BLOB");
}
catch (FileNotFoundException e1) {
e1.printStackTrace();
textArea_1.setText("Private key not found");
}
catch (IOException e1) {
e1.printStackTrace();
textArea_1.setText("Invalid BLOB");
}
catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
textArea_1.setText("Invalid algorithm");
}
catch (NoSuchPaddingException e1) {
e1.printStackTrace();
textArea_1.setText("What");
}
catch (InvalidKeyException e1) {
e1.printStackTrace();
textArea_1.setText("Invalid Key");
}
catch (IllegalBlockSizeException e1) {
e1.printStackTrace();
textArea_1.setText("Invalid Block Size");
}
catch (BadPaddingException e1) {
e1.printStackTrace();
textArea_1.setText("Farts");
}
}
}
});
btnGe.setBounds(12, 289, 105, 27);
contentPane.add(btnGe);
JButton btnGenerator = new JButton("Generator");
btnGenerator.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
KeyPairGeneratorDialog dialog = new KeyPairGeneratorDialog(MainInterface.this);
dialog.setModal(true);
dialog.setVisible(true);
}
});
btnGenerator.setBounds(325, 36, 105, 27);
contentPane.add(btnGenerator);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(12, 70, 420, 83);
contentPane.add(scrollPane);
textArea.setLineWrap(true);
scrollPane.setViewportView(textArea);
JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setBounds(12, 194, 420, 83);
contentPane.add(scrollPane_1);
textArea_1.setLineWrap(true);
scrollPane_1.setViewportView(textArea_1);
loadProperties();
}
public static byte[] readKeyBytes(File file) {
BufferedReader reader = null;
String key = "";
try {
reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
key += line;
}
}
catch (IOException ed) {
return null;
}
finally {
if (reader != null) {
try {
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
String privateKeyPEM = key.replaceAll("-----BEGIN [A-Z]+ KEY-----", "").replace("\n", "").replace("\r", "").replaceAll("-----END [A-Z]+ KEY-----", "");
try {
return Base64.decode(privateKeyPEM);
}
catch (IOException e) {
return null;
}
}
public PrivateKey readPKCS8PrivateKey(File file) {
byte[] encoded = readKeyBytes(file);
if(encoded == null) {
return null;
}
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
return keyFactory.generatePrivate(keySpec);
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
catch (InvalidKeySpecException e) {
e.printStackTrace();
return null;
}
}
public boolean setKeyFile(File file, Component parent) {
PrivateKey key = readPKCS8PrivateKey(file);
if (key == null) {
JOptionPane.showMessageDialog(parent, "Failed to read private key");
this.storeProperties();
return false;
}
else {
keyFile = file;
pk = key;
textField.setText(keyFile.getPath());
this.storeProperties();
return true;
}
}
}