From 7d0e773196152dc8cc26d1f7acfdd866c2b6d1f5 Mon Sep 17 00:00:00 2001 From: bruno Date: Fri, 5 Apr 2024 14:52:37 +0200 Subject: [PATCH] Add asymetric encryption --- .../chatencryptor/ChatDecryptorClient.java | 31 ------ .../chatencryptor/ChatEncryptorClient.java | 21 ---- .../systems/brn/chatencryptor/SecureChat.java | 99 +++++++++++++++++++ src/main/resources/fabric.mod.json | 3 +- 4 files changed, 100 insertions(+), 54 deletions(-) delete mode 100644 src/main/java/systems/brn/chatencryptor/ChatDecryptorClient.java delete mode 100644 src/main/java/systems/brn/chatencryptor/ChatEncryptorClient.java create mode 100644 src/main/java/systems/brn/chatencryptor/SecureChat.java diff --git a/src/main/java/systems/brn/chatencryptor/ChatDecryptorClient.java b/src/main/java/systems/brn/chatencryptor/ChatDecryptorClient.java deleted file mode 100644 index 7c95699..0000000 --- a/src/main/java/systems/brn/chatencryptor/ChatDecryptorClient.java +++ /dev/null @@ -1,31 +0,0 @@ -package systems.brn.chatencryptor; - -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableTextContent; -import java.util.Base64; - -public class ChatDecryptorClient implements ClientModInitializer { - @Override - public void onInitializeClient() { - ClientLifecycleEvents.CLIENT_STARTED.register(client -> { - // Register event listener for ClientTickEvents.END_CLIENT_TICK - ClientReceiveMessageEvents.ALLOW_CHAT.register((message, signedMessage, sender, params, receptionTimestamp) -> { - TranslatableTextContent content = (TranslatableTextContent) message.getContent(); - String message_content = content.getArg(1).getString(); - if(message_content.startsWith("BRNCrypt:")){ - String strippedMessage = message_content.replace("BRNCrypt:", ""); - String decodedMessage = new String(Base64.getDecoder().decode(strippedMessage)); - assert sender != null; - String outputMessage = "Decoded from " + sender.getName() + ":" + decodedMessage; - MinecraftClient.getInstance().inGameHud.getChatHud().addMessage(Text.of(outputMessage)); - return false; - } - return true; - }); - }); - } -} diff --git a/src/main/java/systems/brn/chatencryptor/ChatEncryptorClient.java b/src/main/java/systems/brn/chatencryptor/ChatEncryptorClient.java deleted file mode 100644 index cd405e6..0000000 --- a/src/main/java/systems/brn/chatencryptor/ChatEncryptorClient.java +++ /dev/null @@ -1,21 +0,0 @@ -package systems.brn.chatencryptor; - -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.message.v1.ClientSendMessageEvents; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; - -public class ChatEncryptorClient implements ClientModInitializer { - @Override - public void onInitializeClient() { - ClientLifecycleEvents.CLIENT_STARTED.register(client -> { - // Register event listener for ClientTickEvents.END_CLIENT_TICK - ClientSendMessageEvents.MODIFY_CHAT.register(message -> { - String encodedMessage = Base64.getEncoder().withoutPadding().encodeToString(message.getBytes(StandardCharsets.UTF_8)); - return "BRNCrypt:" + encodedMessage; - }); - }); - } -} diff --git a/src/main/java/systems/brn/chatencryptor/SecureChat.java b/src/main/java/systems/brn/chatencryptor/SecureChat.java new file mode 100644 index 0000000..143c374 --- /dev/null +++ b/src/main/java/systems/brn/chatencryptor/SecureChat.java @@ -0,0 +1,99 @@ +package systems.brn.chatencryptor; + +import com.mojang.authlib.GameProfile; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; +import net.fabricmc.fabric.api.client.message.v1.ClientSendMessageEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.network.message.MessageType; +import net.minecraft.network.message.SignedMessage; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; +import org.jetbrains.annotations.Nullable; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.time.Instant; +import java.util.Base64; + +public class SecureChat implements ClientModInitializer { + + private PublicKey publicKey; + private PrivateKey privateKey; + private Cipher encryptingCipher = null; + private Cipher decryptingCipher = null; + + private void initKeys() { + KeyPairGenerator kpg = null; + try { + kpg = KeyPairGenerator.getInstance("RSA"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + kpg.initialize(1024); + KeyPair kp = kpg.genKeyPair(); + publicKey = kp.getPublic(); + privateKey = kp.getPrivate(); + + try { + encryptingCipher = Cipher.getInstance("RSA"); + decryptingCipher = Cipher.getInstance("RSA"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } catch (NoSuchPaddingException e) { + throw new RuntimeException(e); + } + try { + encryptingCipher.init(Cipher.ENCRYPT_MODE, publicKey); + decryptingCipher.init(Cipher.DECRYPT_MODE, privateKey); + } catch (InvalidKeyException e) { + throw new RuntimeException(e); + } + } + + private boolean decryptChatMessage(Text message, @Nullable SignedMessage signedMessage, @Nullable GameProfile sender, MessageType.Parameters params, Instant receptionTimestamp) { + TranslatableTextContent content = (TranslatableTextContent) message.getContent(); + String message_content = content.getArg(1).getString(); + if(message_content.startsWith("BRNCrypt:")){ + try { + String strippedMessage = message_content.replace("BRNCrypt:", ""); + byte[] decodedMessage = Base64.getDecoder().decode(strippedMessage); + String decryptedMessage = new String(decryptingCipher.doFinal(decodedMessage)); + assert sender != null; + String outputMessage = "{" + sender.getName() + "} " + decryptedMessage; + MinecraftClient.getInstance().inGameHud.getChatHud().addMessage(Text.of(outputMessage)); + return false; + } + catch (IllegalBlockSizeException | BadPaddingException e){ + return true; + } + } + return true; + } + + private String encryptChatMessage(String message) { + encryptingCipher.update(message.getBytes(StandardCharsets.UTF_8)); + String encodedMessage = null; + try { + encodedMessage = Base64.getEncoder().withoutPadding().encodeToString(encryptingCipher.doFinal()); + } catch (IllegalBlockSizeException | BadPaddingException e) { + throw new RuntimeException(e); + } + return "BRNCrypt:" + encodedMessage; + } + + @Override + public void onInitializeClient() { + ClientLifecycleEvents.CLIENT_STARTED.register(client -> { + // Register event listener for ClientTickEvents.END_CLIENT_TICK + initKeys(); + ClientReceiveMessageEvents.ALLOW_CHAT.register(this::decryptChatMessage); + ClientSendMessageEvents.MODIFY_CHAT.register(this::encryptChatMessage); + }); + } +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index e74867e..fa1133b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -16,8 +16,7 @@ "environment": "client", "entrypoints": { "client": [ - "systems.brn.chatencryptor.ChatEncryptorClient", - "systems.brn.chatencryptor.ChatDecryptorClient" + "systems.brn.chatencryptor.SecureChat" ] }, "depends": {