Réécriture du serveur, avec des clés d'encryption partout. Semble compliqué. Risque de disparaître.
This commit is contained in:
parent
668e472e71
commit
a41f44080d
@ -28,6 +28,9 @@ public class Parametres {
|
|||||||
|
|
||||||
public String lookAndFeel = "flatlaf-darcula";
|
public String lookAndFeel = "flatlaf-darcula";
|
||||||
|
|
||||||
|
public String encryptionAlg = "RSA";
|
||||||
|
public int encryptionKeySize = 2048;
|
||||||
|
|
||||||
public Parametres() {
|
public Parametres() {
|
||||||
Map<TextAttribute, Object> ftAttrs = new HashMap<>(minielTitleFont.getAttributes());
|
Map<TextAttribute, Object> ftAttrs = new HashMap<>(minielTitleFont.getAttributes());
|
||||||
ftAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
|
ftAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import java.util.UUID;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.bernard.util.BytesUtils;
|
|
||||||
import com.bernard.util.ParseUtils;
|
import com.bernard.util.ParseUtils;
|
||||||
|
|
||||||
public class Serveur {
|
public class Serveur {
|
||||||
@ -31,19 +30,19 @@ public class Serveur {
|
|||||||
|
|
||||||
boolean networkOnSeparatedThread = false;
|
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 {
|
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 {
|
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 {
|
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[]>();
|
byteArrays = new HashMap<UUID, byte[]>();
|
||||||
receivedSlicesArray = new HashMap<UUID, boolean[]>();
|
receivedSlicesArray = new HashMap<UUID, boolean[]>();
|
||||||
@ -85,17 +84,14 @@ public class Serveur {
|
|||||||
System.arraycopy(data, paquet.getOffset()+41, bigData, offset, paquet.getLength()-41);
|
System.arraycopy(data, paquet.getOffset()+41, bigData, offset, paquet.getLength()-41);
|
||||||
recievedArray[sliceId] = true;
|
recievedArray[sliceId] = true;
|
||||||
if(!ParseUtils.and(recievedArray)) {
|
if(!ParseUtils.and(recievedArray)) {
|
||||||
ByteBuffer dataBuffer = ByteBuffer.wrap(bigData);
|
consumer.accept(bigData,paquet.getSocketAddress());
|
||||||
consumer.accept(dataBuffer,paquet.getSocketAddress());
|
|
||||||
byteArrays.remove(uuid);
|
byteArrays.remove(uuid);
|
||||||
receivedSlicesArray.remove(uuid);
|
receivedSlicesArray.remove(uuid);
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
byte[] realData = new byte[paquet.getLength()];
|
byte[] realData = new byte[paquet.getLength()];
|
||||||
System.arraycopy(data, paquet.getOffset(), realData, 0, paquet.getLength());
|
System.arraycopy(data, paquet.getOffset(), realData, 0, paquet.getLength());
|
||||||
ByteBuffer dataBuffer = ByteBuffer.wrap(realData);
|
consumer.accept(data,paquet.getSocketAddress());
|
||||||
BytesUtils.dump(dataBuffer);
|
|
||||||
consumer.accept(dataBuffer,paquet.getSocketAddress());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
16
src/main/java/com/bernard/murder/server/Codes.java
Normal file
16
src/main/java/com/bernard/murder/server/Codes.java
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
12
src/main/java/com/bernard/murder/server/CommandedServer.java
Normal file
12
src/main/java/com/bernard/murder/server/CommandedServer.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package com.bernard.murder.server;
|
||||||
|
|
||||||
|
import com.bernard.murder.audio.Serveur;
|
||||||
|
|
||||||
|
public class CommandedServer {
|
||||||
|
|
||||||
|
Serveur serveur;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
48
src/main/java/com/bernard/murder/server/Device.java
Normal file
48
src/main/java/com/bernard/murder/server/Device.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
31
src/main/java/com/bernard/murder/server/DeviceType.java
Normal file
31
src/main/java/com/bernard/murder/server/DeviceType.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
96
src/main/java/com/bernard/murder/server/ServeurMaitre.java
Normal file
96
src/main/java/com/bernard/murder/server/ServeurMaitre.java
Normal 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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user