Salta el contingut
 

Pràctica 4: Seguretat i criptografia

Joan Puigcerver Ibáñez

j.puigcerveribanez@edu.gva.es

Llicència: CC BY-NC-SA 4.0

(Reconeixement - NoComercial - CompartirIgual) 🅭

Entrega

L'entrega ha de complir els següents requisits:

  • El codi ha d'estar en el paquet corresponent: ud4.practices
  • El nom de la classe on comença l'execució (main()) de cada exercici és el títol de l'exercici.
  • El format de la eixida del programa ha de ser consistent amb el format demanat.
  • S'ha d'entregar un fitxer .zip amb el contingut del paquet.
  • El codi ha d'estar pujat a GitHub en el vostre repositori de l'assignatura.
  • Tag GitHub: PracticeCrypt (StackOverflow: Create a tag in a GitHub repository)

FileEncryption

ud4.practices.fileencryption

Crea la aplicació FileEncryption que permeta crear, llegir i escriure en fitxers encriptats mitjançant l'algorisme AES.

L'aplicació mostrarà un menú del tipus i permetrà a l'usuari realitzar les següents accions:

Benvingut a FileEncryption:
1) Escriure un fitxer
2) Llegir un fitxer
0) Eixir.

L'acció Eixir acabarà el programa.

Advertència

El codi ha d'estar ben estructurat en mètodes i classes.

Escriure un fitxer

L'usuari indicarà la ruta del fitxer on vol guardar la informació i comprovarà si el fitxer existeix.

  • Si existeix, preguntarà a l'usuari per la confirmació per ser sobreescrit. Si no ho confirma, torna al menu principal.

Li demanarà a l'usuari una contrasenya i crearà una SecretKey a partir d'ella.

El programa demanarà a l'usuari que escriga per pantalla tota la informació que vol guardar en el fitxer. Deixarà de demanar-li la informació quan l'usuari escriga una línia amb el contingut \exit.

Finalment, encriptarà tot el contingut i el guardarà en el fitxer especificat.

Llegir un fitxer

L'usuari indicarà la ruta del fitxer que vol llegir i comprovarà si el fitxer existeix.

  • Si no existeix, mostrarà un missatge d'error i tornarà al menú principal.

Li demanarà a l'usuari una contrasenya i crearà una SecretKey a partir d'ella. Finalment, intentarà desencriptar el fitxer.

Si la desencriptació ha segut satisfactòria, mostrara el contingut del fitxer desencriptat per pantalla. En altre cas (per exemple, perquè la contrasenya no és l'adequada o el fitxer no estava encriptat), mostrarà un missatge d'error.

SSLSocket: Chat

ud4.practices.chat

Adapta el codi de l'aplicació de l'Exercici: Chat perquè utilitze SSLSockets.

Codi de l'exercici Chat solucionat
  • Client:

    ChatClient.java
    package ud3.exercises.chat.client;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class ChatClient {
        private final Socket socket;
        private final ChatClientListener listener;
        private final Scanner scanner;
        private final PrintWriter out;
    
        public ChatClient(String host, int port) throws IOException {
            this.scanner = new Scanner(System.in);
            this.socket = new Socket(host, port);
            this.out = new PrintWriter(socket.getOutputStream(), true);
            this.listener = new ChatClientListener(socket.getInputStream());
        }
    
        public void identify(){
            System.out.print("Introdueix el teu nom: ");
            String line = scanner.nextLine();
            out.println(line);
            listener.start();
        }
    
        public void chat() throws IOException {
            System.out.println("Acabes d'entrar al chat.");
            System.out.println("Per exir, escriu \"/exit\".");
            String line;
            while(!(line = scanner.nextLine()).equals("/exit") && this.socket.isConnected()){
                out.println(line);
            }
            close();
        }
    
        public void close(){
            try {
                socket.close();
                listener.interrupt();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
        public static void main(String[] args) {
            System.out.println("Connectant-se amb el servidor...");
            try {
                ChatClient chat = new ChatClient("localhost", 1234);
                chat.identify();
                chat.chat();
            } catch (IOException e){
                System.err.println("Error connectant-se amb el servidor.");
            }
        }
    }
    
    ChatClientListener.java
    package ud3.exercises.chat.client;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.Socket;
    
    public class ChatClientListener extends Thread {
    
        private final BufferedReader in;
    
        public ChatClientListener(InputStream inputStream) throws IOException {
            in = new BufferedReader(new InputStreamReader(inputStream));
        }
    
        @Override
        public void run() {
            String line;
            try {
                while ((line = in.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException ignored ){
            }
        }
    }
    
  • Servidor:

    ChatServer.java
    package ud3.exercises.chat.server;
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class ChatServer extends Thread {
        ServerSocket server;
    
        List<ChatServerHandler> clients;
        boolean running;
    
        public ChatServer(int port) throws IOException {
            server = new ServerSocket(port);
            clients = new ArrayList<>();
            running = true;
        }
    
        public void close(){
            running = false;
            this.interrupt();
        }
    
        public synchronized void removeClient(ChatServerHandler client){
            clients.remove(client);
        }
    
        public void sendMessage(String msg){
            for(ChatServerHandler client : clients) {
                client.sendMessage(msg);
            }
        }
    
        public void sendMessage(String alias, String msg){
            clients.stream()
                    .filter(client -> !client.getNom().equals(alias))
                    .forEach(client -> client.sendMessage(msg));
        }
    
        @Override
        public void run() {
            while (running){
                try {
                    Socket client = server.accept();
                    ChatServerHandler handler = new ChatServerHandler(client, this);
                    clients.add(handler);
                    handler.start();
                    System.out.println("Nova connexió acceptada.");
                } catch (IOException e) {
                    System.err.println("Error while accepting new connection");
                    System.err.println(e.getMessage());
                }
            }
        }
    
        public static void main(String[] args) {
            try {
                Scanner scanner = new Scanner(System.in);
                ChatServer server = new ChatServer(1234);
                server.start();
    
                scanner.nextLine();
    
                server.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
    
        }
    }
    
    ChatServerHandler.java
    package ud3.exercises.chat.server;
    
    import java.io.*;
    import java.net.Socket;
    
    public class ChatServerHandler extends Thread {
        private final Socket socket;
        private final ChatServer server;
        private final PrintWriter out;
        private final BufferedReader in;
    
        private String nom;
        public ChatServerHandler(Socket socket, ChatServer server) throws IOException {
            this.socket = socket;
            this.server = server;
    
            this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            this.out = new PrintWriter(socket.getOutputStream(), true);
        }
    
        public String getNom() {
            return nom;
        }
    
        public void setNom(String nom) {
            this.nom = nom;
        }
    
        public void sendMessage(String message){
            out.println(message);
        }
    
        @Override
        public void run(){
            try {
                String nom = in.readLine();
                setNom(nom);
    
                System.out.printf("%s s'ha identificat.\n", getNom());
    
                // Quan un client es desconecta, l'operació readLine() retorna null
                String message;
                while((message = in.readLine()) != null){
                    String messageWithName = String.format("%s: %s", getNom(), message);
                    System.out.println(messageWithName);
                    server.sendMessage(messageWithName);
                }
                System.out.printf("%s has disconnected.\n", getNom());
                socket.close();
            } catch (IOException e) {
                System.err.println(e.getMessage());
            } finally {
                server.removeClient(this);
            }
        }
    }
    

Cal generar:

  • KeyStore de ChatServer: Guardar-la al fitxer files/ud4/chat/chat-server.jks.

    Indica la comanda utilitzada com a comentari en el moment que es cree el SSLServerSocket en la classe ChatServer.

    Important

    La informació del certificat de mostrar per terminal quan inicie el servidor.

    Certificat:

    Camp Valor
    Àlies chat-server
    CN ChatServer
    OU PSP-DAM2S
    O CIPFP Mislata
    L Mislata
    ST València
    C ES
  • TrustStore de ChatClient: Guardar-la al fitxer files/ud4/chat/chat-client.jks.

    Indica la comanda utilitzada com a comentari en el moment que es cree el SSLServerSocket en la classe ChatClient.

    • Cal importar el certificat del servidor generat anteriorment.
📌 Aquest document pot quedar desactualitzat després d’imprimir-lo. Pots consultar la versió més recent a la pàgina web.
🌿 Abans d’imprimir aquest document, considera si és realment necessari. Redueix el consum de paper i ajuda a protegir el nostre entorn.