Réécriture du serveur, avec des clés d'encryption partout. Semble compliqué. Risque de disparaître.

This commit is contained in:
Mysaa 2021-08-27 02:17:17 +02:00
parent 668e472e71
commit a41f44080d
7 changed files with 213 additions and 11 deletions

View File

@ -28,6 +28,9 @@ public class Parametres {
public String lookAndFeel = "flatlaf-darcula";
public String encryptionAlg = "RSA";
public int encryptionKeySize = 2048;
public Parametres() {
Map<TextAttribute, Object> ftAttrs = new HashMap<>(minielTitleFont.getAttributes());
ftAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);

View File

@ -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<ByteBuffer,SocketAddress> consumer;
BiConsumer<Object,SocketAddress> consumer; // Where object has type byte[]
public Serveur(Consumer<ByteBuffer> 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<ByteBuffer> 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<ByteBuffer,SocketAddress> 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<ByteBuffer,SocketAddress> dataEater,SocketAddress adresse) throws SocketException {
public Serveur(BiConsumer<Object,SocketAddress> dataEater,SocketAddress adresse) throws SocketException {
byteArrays = new HashMap<UUID, byte[]>();
receivedSlicesArray = new HashMap<UUID, boolean[]>();
@ -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) {

View File

@ -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;
}

View File

@ -0,0 +1,12 @@
package com.bernard.murder.server;
import com.bernard.murder.audio.Serveur;
public class CommandedServer {
Serveur serveur;
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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<SocketAddress,Device> devices;
public ServeurMaitre(String name, int port) throws UnknownHostException, SocketException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
serveur = new Serveur((BiConsumer<Object,SocketAddress>)(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) {
}
}