Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
AshSta512 committed Nov 7, 2023
0 parents commit 78712b6
Show file tree
Hide file tree
Showing 12 changed files with 571 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target/
/Encrypter.iml
/pom.xml
143 changes: 143 additions & 0 deletions src/main/java/net/ashsta/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package net.ashsta;

import net.ashsta.components.*;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.net.URL;

public class App {

public static final Font FONT = new Font("Default", Font.PLAIN, 24);
public static final Font BUTTON_FONT = new Font("Default", Font.BOLD, 32);
public static final Font POPOUT_BOX_FONT = new Font("Default", Font.PLAIN, 24);
public static final Font MENU_BAR_FONT = new Font("Default", Font.PLAIN, 20);
public static final Border BORDER = BorderFactory.createLineBorder(Color.black);

public static void main(String[] args) {
JFrame jFrame = new JFrame("Encrypter");
URL iconURL = App.class.getClassLoader().getResource("icon.png");
Image iconImage = Toolkit.getDefaultToolkit().createImage(iconURL);
jFrame.setIconImage(iconImage);
jFrame.setSize(new Dimension(1600 - 256 - 32, 960 - 64 - 32));
jFrame.setResizable(false);
jFrame.setLocationRelativeTo(null);
addMenuBar(jFrame);
addComponents(jFrame);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);
}

private static void addMenuBar(JFrame jFrame) {
CustomTextMenuItem newFeaturesMenuItem = new CustomTextMenuItem(jFrame, "New Features",
"<b>Everything is new!</b>",
"<b>How to use the program:</b>",
"Input text into the \"Text Input\" box,",
"(Optional) Enter a password,",
"Press \"Encrypt\" to encrypt text and \"Decrypt\" to decrypt text!",
"<b>More features coming soon!</b>"
);

CustomTextMenuItem faqMenuItem = new CustomTextMenuItem(jFrame, "Frequently Asked Questions",
"<b>Who is this program intended for?</b>",
"Anyone who wants to encrypt/decrypt data using a password.",
"<b>What are some possible uses for this program?</b>",
"Encrypting messages that you only want people who know the password to see.",
"<b>How does the encryption work?</b>",
"Inputted data is transformed using the given password and the AES algorithm.",
"Encrypted data is then converted to a Base64 string for simpler storage!"
);

CustomTextMenuItem contactMenuItem = new CustomTextMenuItem(jFrame, "Contact Information",
"Need more assistance? Contact the developer!",
"Email: [email protected]"
);

JCheckBoxMenuItem advancedModeMenuItem = new JCheckBoxMenuItem("Advanced Mode");
advancedModeMenuItem.setFont(MENU_BAR_FONT);
advancedModeMenuItem.addActionListener(e -> {
boolean state = advancedModeMenuItem.getState();
JLabel jLabel = new JLabel(
"<html>Are you sure you want to " +
(state ? "enable" : "disable") +
" advanced mode? <br>" +
"NOTE: Advanced Mode is not currently implemented and will not affect the program.</html>"
);
jLabel.setFont(POPOUT_BOX_FONT);
int option = JOptionPane.showConfirmDialog(jFrame, jLabel, "Advanced Mode Confirmation", JOptionPane.YES_NO_OPTION);
if (option == JOptionPane.NO_OPTION)
advancedModeMenuItem.setState(!state);
});

JMenu helpMenu = new JMenu("Help");
helpMenu.setBorder(BORDER);
helpMenu.setFont(MENU_BAR_FONT);
helpMenu.add(newFeaturesMenuItem);
helpMenu.add(faqMenuItem);
helpMenu.add(contactMenuItem);

JMenu advancedOptionsMenu = new JMenu("Advanced Options");
advancedOptionsMenu.setBorder(BORDER);
advancedOptionsMenu.setFont(MENU_BAR_FONT);
advancedOptionsMenu.add(advancedModeMenuItem);

JMenuBar jMenuBar = new JMenuBar();
jMenuBar.add(helpMenu);
jMenuBar.add(advancedOptionsMenu);
jFrame.setJMenuBar(jMenuBar);
}

private static void addComponents(JFrame jFrame) {
InputScrollPane inputScrollPane = new InputScrollPane();
CustomLabel inputTextLabel = new CustomLabel("Text Input", inputScrollPane);

OutputHistoryPanel outputHistoryPanel = new OutputHistoryPanel();

PasswordField passwordField = new PasswordField();
CustomLabel passwordFieldLabel = new CustomLabel("Password", passwordField);
ShowPasswordButton showPasswordButton = new ShowPasswordButton(passwordField);

EncryptButton encryptButton = new EncryptButton(jFrame, inputScrollPane, passwordField, outputHistoryPanel);
DecryptButton decryptButton = new DecryptButton(jFrame, inputScrollPane, passwordField, outputHistoryPanel);

// ADD TO JFRAME
Container container = jFrame.getContentPane();
GroupLayout layout = new GroupLayout(container);
container.setLayout(layout);
layout.setAutoCreateGaps(true);

GroupLayout.Group horizontalGroup = layout.createSequentialGroup()
.addGap(64)
.addGroup(layout.createParallelGroup()
.addGroup(layout.createParallelGroup()
.addComponent(inputTextLabel)
.addComponent(inputScrollPane))
.addGroup(layout.createSequentialGroup()
.addComponent(passwordFieldLabel)
.addComponent(showPasswordButton))
.addGroup(layout.createSequentialGroup()
.addComponent(passwordField)
.addGap(64)
.addComponent(encryptButton)
.addGap(64)
.addComponent(decryptButton))
.addComponent(outputHistoryPanel));

GroupLayout.Group verticalGroup = layout.createSequentialGroup()
.addGroup(layout.createSequentialGroup()
.addComponent(inputTextLabel)
.addComponent(inputScrollPane))
.addGroup(layout.createParallelGroup()
.addComponent(passwordFieldLabel)
.addComponent(showPasswordButton))
.addGroup(layout.createParallelGroup()
.addComponent(passwordField)
.addComponent(encryptButton)
.addComponent(decryptButton))
.addComponent(outputHistoryPanel);

layout.setHorizontalGroup(horizontalGroup);
layout.setVerticalGroup(verticalGroup);
}
}
62 changes: 62 additions & 0 deletions src/main/java/net/ashsta/Encryption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package net.ashsta;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.regex.Pattern;

public class Encryption {

private static final Pattern BASE_64_PATTERN = Pattern.compile("^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$");

private static byte[] createFinalKey(byte[] key) {
if (key.length == 16)
return key;
byte[] finalKey = new byte[16];
System.arraycopy(key, 0, finalKey, 0, Math.min(key.length, 16));
return finalKey;
}

public static String encryptBase64(byte[] data, byte[] key) {
if (data == null || data.length == 0)
return null;
byte[] encryptBytes = encrypt(data, key);
if (encryptBytes == null)
return null;
return Base64.getEncoder().encodeToString(encryptBytes);
}

public static String decryptBase64(String base64, byte[] key) {
if (base64 == null || base64.length() == 0 || !BASE_64_PATTERN.matcher(base64).matches())
return null;
byte[] encryptedBytes = Base64.getDecoder().decode(base64);
if (encryptedBytes.length % 16 != 0)
return null;
byte[] decryptedBytes = decrypt(encryptedBytes, key);
if (decryptedBytes == null)
return null;
return new String(decryptedBytes);
}

private static byte[] encrypt(byte[] data, byte[] key) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(createFinalKey(key), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}

private static byte[] decrypt(byte[] data, byte[] key) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(createFinalKey(key), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
}
15 changes: 15 additions & 0 deletions src/main/java/net/ashsta/components/CustomLabel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package net.ashsta.components;

import javax.swing.*;
import java.awt.*;

public class CustomLabel extends JLabel {

private static final Font LABEL_FONT = new Font("Default", Font.PLAIN, 20);

public CustomLabel(String text, Component labelFor) {
setText(text);
setFont(LABEL_FONT);
setLabelFor(labelFor);
}
}
18 changes: 18 additions & 0 deletions src/main/java/net/ashsta/components/CustomTextMenuItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.ashsta.components;

import net.ashsta.App;

import javax.swing.*;

public class CustomTextMenuItem extends JMenuItem {

public CustomTextMenuItem(JFrame jFrame, String title, String... text) {
super(title);
this.setFont(App.MENU_BAR_FONT);
this.addActionListener(e -> {
JLabel jLabel = new JLabel("<html>" + String.join("<br>", text) + "</html>");
jLabel.setFont(App.POPOUT_BOX_FONT);
JOptionPane.showMessageDialog(jFrame, jLabel, title, JOptionPane.INFORMATION_MESSAGE);
});
}
}
30 changes: 30 additions & 0 deletions src/main/java/net/ashsta/components/DecryptButton.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package net.ashsta.components;

import net.ashsta.App;
import net.ashsta.Encryption;

import javax.swing.*;
import java.awt.*;

public class DecryptButton extends JButton {

public DecryptButton(JFrame jFrame, InputScrollPane inputScrollPane, PasswordField passwordField, OutputHistoryPanel outputHistoryPanel) {
this.setMaximumSize(new Dimension(128 + 48, 64));
this.setFont(App.BUTTON_FONT);
this.setText("Decrypt");
this.setBackground(Color.GREEN);
this.addActionListener(e -> {
String input = inputScrollPane.getTextArea().getText();
String password = new String(passwordField.getPassword());
String decryptedText = Encryption.decryptBase64(input, password.getBytes());
if (decryptedText == null) {
JOptionPane.showMessageDialog(jFrame,
"<html>Input was not able to be decrypted!<br>Input and/or Password are not valid.</html>",
"Decryption Error",
JOptionPane.ERROR_MESSAGE);
return;
}
outputHistoryPanel.newOutput(input, password, decryptedText);
});
}
}
30 changes: 30 additions & 0 deletions src/main/java/net/ashsta/components/EncryptButton.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package net.ashsta.components;

import net.ashsta.App;
import net.ashsta.Encryption;

import javax.swing.*;
import java.awt.*;

public class EncryptButton extends JButton {

public EncryptButton(JFrame jFrame, InputScrollPane inputScrollPane, PasswordField passwordField, OutputHistoryPanel outputHistoryPanel) {
this.setMaximumSize(new Dimension(128 + 48, 64));
this.setFont(App.BUTTON_FONT);
this.setText("Encrypt");
this.setBackground(Color.RED);
this.addActionListener(e -> {
String input = inputScrollPane.getTextArea().getText();
String password = new String(passwordField.getPassword());
String encryptedText = Encryption.encryptBase64(input.getBytes(), password.getBytes());
if (encryptedText == null) {
JOptionPane.showMessageDialog(jFrame,
"<html>Input was not able to be encrypted!<br>Input is likely empty.</html>",
"Encryption Error",
JOptionPane.ERROR_MESSAGE);
return;
}
outputHistoryPanel.newOutput(input, password, encryptedText);
});
}
}
25 changes: 25 additions & 0 deletions src/main/java/net/ashsta/components/InputScrollPane.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.ashsta.components;

import net.ashsta.App;

import javax.swing.*;
import java.awt.*;

public class InputScrollPane extends JScrollPane {

private final JTextArea TEXT_AREA;

public InputScrollPane() {
this.setMaximumSize(new Dimension(1280 - 64 - 32 - 4, 256));
this.setBorder(App.BORDER);
TEXT_AREA = new JTextArea();
TEXT_AREA.setFont(App.FONT);
TEXT_AREA.setLineWrap(true);
TEXT_AREA.setWrapStyleWord(true);
this.setViewportView(TEXT_AREA);
}

public JTextArea getTextArea() {
return TEXT_AREA;
}
}
Loading

0 comments on commit 78712b6

Please sign in to comment.