Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/plugin message encrypt #142

Merged
merged 14 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions NookureStaff-API/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ java {
}

dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation(libs.configurateYaml)
compileOnly(libs.protocol.buffers.lite)
compileOnlyApi(libs.paperApi)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.nookure.staff.api.annotation;

import com.google.inject.BindingAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
public @interface PluginMessageSecretKey {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.nookure.staff.api.config.common;

import org.spongepowered.configurate.objectmapping.ConfigSerializable;
import org.spongepowered.configurate.objectmapping.meta.Comment;
import org.spongepowered.configurate.objectmapping.meta.Setting;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;

import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

@ConfigSerializable
public class PluginMessageConfig {
@Setting
public boolean enabled = false;

@Setting
@Comment("""
Base64-encoded encryption key for plugin messages, generated if not present, must be 128, 192, or 256 bits
You should have the same key on all servers in the network
""")
public String encryptionKey;

@Setting
@Comment("""
It's a security feature to prevent players from tampering with the plugin messages
if the plugin detects tampering, it will disconnect the player
""")
public boolean playerTamperingDetection = true;

@Setting
@Comment("""
The message to send to the player when tampering is detected
""")
public String playerTamperingDetectionMessage = "<red>Plugin message tampering detected!";

public PluginMessageConfig() {
ensureEncryptionKey(256);
}

/**
* Generates a new encryption key with the specified length.
*
* @param length Key length in bits (must be 128, 192, or 256)
* @return Base64-encoded encryption key
*/
private String generateEncryptionKey(final int length) {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(length);
SecretKey secretKey = keyGen.generateKey();
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("AES algorithm is not available", e);
}
}

/**
* Retrieves the SecretKey from the stored encryption key.
*
* @return A SecretKey instance
*/
public SecretKey getSecretKey() {
if (encryptionKey == null || encryptionKey.isEmpty()) {
throw new IllegalStateException("Encryption key is not set");
}

byte[] decodedKey = Base64.getDecoder().decode(encryptionKey);
return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
}

/**
* Generates and sets a new encryption key if none is present.
*/
public void ensureEncryptionKey(final int length) {
if (encryptionKey == null || encryptionKey.isEmpty()) {
encryptionKey = generateEncryptionKey(length);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.nookure.staff.api.exception;

public class DataIntegrityCheckFailedException extends RuntimeException {
public DataIntegrityCheckFailedException(String message) {
super(message);
}

public DataIntegrityCheckFailedException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

public class Channels {
public static final String EVENTS = "nkstaff:events";
public static final String COMMANDS = "nkstaff:commands";
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@
import java.util.Optional;

public abstract class EventMessenger implements AutoCloseable {
private final Logger logger;
private final NookureStaff plugin;

@Inject
private Logger logger;
@Inject
private NookureStaff plugin;
public EventMessenger(
@NotNull final Logger logger,
@NotNull final NookureStaff plugin
) {
this.logger = logger;
this.plugin = plugin;
}

/**
* Prepares the event transport for use.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.nookure.staff.api.service;

import org.jetbrains.annotations.NotNull;

import javax.crypto.SecretKey;

public interface EncryptService {
/**
* Encrypts the given data with the given secret key.
*
* @param data The data to encrypt.
* @param secretKey The secret key to encrypt the data with.
* @return The encrypted data.
*/
byte @NotNull [] encrypt(byte @NotNull [] data, @NotNull final SecretKey secretKey);

/**
* Decrypts the given data with the given secret key.
*
* @param data The data to decrypt.
* @param secretKey The secret key to decrypt the data with.
* @return The decrypted data.
*/
byte @NotNull [] decrypt(byte @NotNull [] data, @NotNull final SecretKey secretKey);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.nookure.staff.api.util;

import com.nookure.staff.api.Permissions;
import com.nookure.staff.api.PlayerWrapper;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -55,6 +56,14 @@ public void broadcastStaffMessage(@NotNull String message) {
broadcast(message, Permissions.STAFF_PERMISSION);
}

/**
* Send a command to the proxy server console
*
* @param command The command to send
* @param sender The sender of the command
*/
abstract public void sendCommandToProxy(@NotNull String command, @NotNull PlayerWrapper sender);

static {
isPaper = hasClass("com.destroystokyo.paper.PaperConfig") ||
hasClass("io.papermc.paper.configuration.Configuration");
Expand Down
24 changes: 0 additions & 24 deletions NookureStaff-BungeeCord/build.gradle.kts

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading