From a41f44080d21e688bef582ae67916f0d87d57521 Mon Sep 17 00:00:00 2001 From: Mysaa Date: Fri, 27 Aug 2021 02:17:17 +0200 Subject: [PATCH] =?UTF-8?q?R=C3=A9=C3=A9criture=20du=20serveur,=20avec=20d?= =?UTF-8?q?es=20cl=C3=A9s=20d'encryption=20partout.=20Semble=20compliqu?= =?UTF-8?q?=C3=A9.=20Risque=20de=20dispara=C3=AEtre.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bernard/murder/Parametres.java | 3 + .../com/bernard/murder/audio/Serveur.java | 18 ++-- .../java/com/bernard/murder/server/Codes.java | 16 ++++ .../murder/server/CommandedServer.java | 12 +++ .../com/bernard/murder/server/Device.java | 48 ++++++++++ .../com/bernard/murder/server/DeviceType.java | 31 ++++++ .../bernard/murder/server/ServeurMaitre.java | 96 +++++++++++++++++++ 7 files changed, 213 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/bernard/murder/server/Codes.java create mode 100644 src/main/java/com/bernard/murder/server/CommandedServer.java create mode 100644 src/main/java/com/bernard/murder/server/Device.java create mode 100644 src/main/java/com/bernard/murder/server/DeviceType.java create mode 100644 src/main/java/com/bernard/murder/server/ServeurMaitre.java diff --git a/src/main/java/com/bernard/murder/Parametres.java b/src/main/java/com/bernard/murder/Parametres.java index db74a94..7359aa2 100644 --- a/src/main/java/com/bernard/murder/Parametres.java +++ b/src/main/java/com/bernard/murder/Parametres.java @@ -28,6 +28,9 @@ public class Parametres { public String lookAndFeel = "flatlaf-darcula"; + public String encryptionAlg = "RSA"; + public int encryptionKeySize = 2048; + public Parametres() { Map ftAttrs = new HashMap<>(minielTitleFont.getAttributes()); ftAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); diff --git a/src/main/java/com/bernard/murder/audio/Serveur.java b/src/main/java/com/bernard/murder/audio/Serveur.java index 8913b57..6e4cb45 100755 --- a/src/main/java/com/bernard/murder/audio/Serveur.java +++ b/src/main/java/com/bernard/murder/audio/Serveur.java @@ -14,7 +14,6 @@ import java.util.UUID; import java.util.function.BiConsumer; import java.util.function.Consumer; -import com.bernard.util.BytesUtils; import com.bernard.util.ParseUtils; public class Serveur { @@ -31,19 +30,19 @@ public class Serveur { boolean networkOnSeparatedThread = false; - BiConsumer consumer; + BiConsumer consumer; // Where object has type byte[] public Serveur(Consumer dataEater, int port) throws UnknownHostException, SocketException { - this((b,i)->dataEater.accept(b),new InetSocketAddress(port)); + this((o,s) -> dataEater.accept(ByteBuffer.wrap((byte[])o)),new InetSocketAddress(port)); } public Serveur(Consumer dataEater,SocketAddress addresse) throws UnknownHostException, SocketException { - this((b,i)->dataEater.accept(b),addresse); + this((o,s) -> dataEater.accept(ByteBuffer.wrap((byte[])o)),addresse); } public Serveur(BiConsumer dataEater,int port) throws UnknownHostException, SocketException { - this(dataEater,new InetSocketAddress(port)); + this((o,s) -> dataEater.accept(ByteBuffer.wrap((byte[])o),s),new InetSocketAddress(port)); } - public Serveur(BiConsumer dataEater,SocketAddress adresse) throws SocketException { + public Serveur(BiConsumer dataEater,SocketAddress adresse) throws SocketException { byteArrays = new HashMap(); receivedSlicesArray = new HashMap(); @@ -85,17 +84,14 @@ public class Serveur { System.arraycopy(data, paquet.getOffset()+41, bigData, offset, paquet.getLength()-41); recievedArray[sliceId] = true; if(!ParseUtils.and(recievedArray)) { - ByteBuffer dataBuffer = ByteBuffer.wrap(bigData); - consumer.accept(dataBuffer,paquet.getSocketAddress()); + consumer.accept(bigData,paquet.getSocketAddress()); byteArrays.remove(uuid); receivedSlicesArray.remove(uuid); } }else { byte[] realData = new byte[paquet.getLength()]; System.arraycopy(data, paquet.getOffset(), realData, 0, paquet.getLength()); - ByteBuffer dataBuffer = ByteBuffer.wrap(realData); - BytesUtils.dump(dataBuffer); - consumer.accept(dataBuffer,paquet.getSocketAddress()); + consumer.accept(data,paquet.getSocketAddress()); } } catch (IOException e) { diff --git a/src/main/java/com/bernard/murder/server/Codes.java b/src/main/java/com/bernard/murder/server/Codes.java new file mode 100644 index 0000000..b68b759 --- /dev/null +++ b/src/main/java/com/bernard/murder/server/Codes.java @@ -0,0 +1,16 @@ +package com.bernard.murder.server; + +public class Codes { + + // NETWORKING + + // [commande 1, UUID requestId] + public static final byte PING = 0x00; + public static final byte PONG = 0x01; + + // [commande 1] + public static final byte ASK_PUBKEY = 0x02; + // [commande 1, byteCount int, byte[] key] + public static final byte GIVE_PUBKEY = 0x03; + +} diff --git a/src/main/java/com/bernard/murder/server/CommandedServer.java b/src/main/java/com/bernard/murder/server/CommandedServer.java new file mode 100644 index 0000000..246358d --- /dev/null +++ b/src/main/java/com/bernard/murder/server/CommandedServer.java @@ -0,0 +1,12 @@ +package com.bernard.murder.server; + +import com.bernard.murder.audio.Serveur; + +public class CommandedServer { + + Serveur serveur; + + + + +} diff --git a/src/main/java/com/bernard/murder/server/Device.java b/src/main/java/com/bernard/murder/server/Device.java new file mode 100644 index 0000000..c236416 --- /dev/null +++ b/src/main/java/com/bernard/murder/server/Device.java @@ -0,0 +1,48 @@ +package com.bernard.murder.server; + +import java.net.SocketAddress; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +import com.bernard.murder.Parametres; + +public class Device { + + DeviceType type; + String nom; + + PublicKey cle; + SocketAddress addresse; + + public Device(DeviceType type, String nom, PublicKey cle, SocketAddress addresse) { + super(); + this.type = type; + this.nom = nom; + this.cle = cle; + this.addresse = addresse; + } + + public byte[] decryptReceivedMessage(byte[] message) { + try { + Cipher decodeur; + decodeur = Cipher.getInstance(Parametres.instance.encryptionAlg); + decodeur.init(Cipher.DECRYPT_MODE, this.cle); + + return decodeur.doFinal(message); + } catch (NoSuchAlgorithmException | + NoSuchPaddingException | + InvalidKeyException | + IllegalBlockSizeException | + BadPaddingException e) { + throw new IllegalStateException("Impossible d'initialiser le décodeur pour l'appareil à l'adresse "+addresse.toString(),e); + } + } + + +} diff --git a/src/main/java/com/bernard/murder/server/DeviceType.java b/src/main/java/com/bernard/murder/server/DeviceType.java new file mode 100644 index 0000000..76e2920 --- /dev/null +++ b/src/main/java/com/bernard/murder/server/DeviceType.java @@ -0,0 +1,31 @@ +package com.bernard.murder.server; + +import java.util.Arrays; + +public enum DeviceType { + + TerminalMaitre(0x00), + TerminalEsclave(0x01), + Microphone(0x10), + Enceinte(0x11), + JoueurPhone(0x20), + OpPhone(0x21); + + private byte code; + + private DeviceType(byte code) { + this.code = code; + } + private DeviceType(int code) { + this((byte)code); + } + + public byte getCode() { + return code; + } + + public static DeviceType of(byte code) { + return Arrays.stream(DeviceType.values()).filter(d -> d.getCode()==code).findAny().orElse(null); + } + +} diff --git a/src/main/java/com/bernard/murder/server/ServeurMaitre.java b/src/main/java/com/bernard/murder/server/ServeurMaitre.java new file mode 100644 index 0000000..28621ec --- /dev/null +++ b/src/main/java/com/bernard/murder/server/ServeurMaitre.java @@ -0,0 +1,96 @@ +package com.bernard.murder.server; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.SecureRandom; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +import com.bernard.murder.Parametres; +import com.bernard.murder.audio.Serveur; + +public class ServeurMaitre { + + private Serveur serveur; + + private PrivateKey masterPrivateKey; + private Cipher encodeur; + + private Map devices; + + + public ServeurMaitre(String name, int port) throws UnknownHostException, SocketException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { + serveur = new Serveur((BiConsumer)(this::globalCommandReceiver), new InetSocketAddress(port)); + + SecureRandom srand = new SecureRandom(); + KeyPairGenerator kpg = KeyPairGenerator.getInstance(Parametres.instance.encryptionAlg); + kpg.initialize(Parametres.instance.encryptionKeySize, srand); + + KeyPair kpair = kpg.generateKeyPair(); + this.masterPrivateKey = kpair.getPrivate(); + + // Renvoie une erreur si le cipher n'existe pas. + this.encodeur = Cipher.getInstance(Parametres.instance.encryptionAlg); + this.encodeur.init(Cipher.ENCRYPT_MODE, masterPrivateKey); + + Device thisDevice = new Device(DeviceType.TerminalMaitre, name, kpair.getPublic(), serveur.getAddress()); + + devices = new HashMap<>(); + devices.put(serveur.getAddress(), thisDevice); + } + + /* + * + * Toutes les commandes sont encryptées avec la clé de l'envoyeur, sauf + * les commandes de ping et récupération de la clé publique du maître + * + */ + + public void globalCommandReceiver(Object untypedData, SocketAddress sender) { + byte[] data = (byte[]) untypedData; + if(devices.containsKey(sender)) { + // Alors on déchiffre avant de faire avaler. + Device sendingDevice = devices.get(sender); + + byte[] realMessage = sendingDevice.decryptReceivedMessage(data); + + uncryptedCommandReceiver(ByteBuffer.wrap(realMessage), sendingDevice); + + }else { + // La commande ne dois pas être encryptée + ByteBuffer donnees = ByteBuffer.wrap(data); + byte commande = donnees.get(); + switch(commande) { + case Codes.PING: + case Codes.PONG: + case Codes.ASK_PUBKEY: + //case Codes.GIVE_PUBKEY: Inutile pour le master, les clés sont données à l'enregistrement. + + + default: + System.err.println("J'ai reçu une commande qui devrait être encryptée !!!"); + } + } + } + + private void uncryptedCommandReceiver(ByteBuffer data, Device sender) { + + } + + public void audioCommandReceiver(ByteBuffer data, Device device) { + + } + +}