codice:
package AstaCrittografata;

/**
 *
 * @author Matteo
 */
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.*;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.*;
import javax.crypto.Cipher;
import AstaCrittografata.Inserzione;
import java.io.*;

/**
 * Questo è un esempio di un'applicazione che garantisce autenticazione del
 * mittente. Il server genera una coppia di chiavi e comunica la chiave pubblica
 * a chi ne fa richiesta. In seguito ogni comunicazione in uscita sarà cifrata
 * con la chiave privata. I client, che decifrano i messaggi con la chiave
 * pubblica sapranno che può essere stato solo questo server ad inviare i dati,
 * perché è l'unica entità a disposizione della chiave privata originale.
 *

 *
 */
class AstaServer {
    protected GestoreUtenti gestU=new GestoreUtenti();
    private ArrayList< Offerta> offerte;
    private Calendar limite;
    private AstaAccepter accepter;
    private AstaDenier denier;
    private int port;
    // Cryptography: begin
    // Thread per la gestione dell'invio della chiave pubblica
    private InviaKey inviaKey;
    // Cipher per la decifrazione dei dati inviati dallo scommettitore
    private Cipher decipher;
    // Cipher per la cifrazione dei dati da inviare allo scommettitore
    private Cipher cipher;
    // Coppia di chiavi pubblica e privata
    KeyPair kp;

    // Cryptography: end
    public AstaServer(int port, int getKeyPort, Calendar deadline) {

        // Cryptography: begin
        // Avvio il server per l'invio della chiave pubblica
        inviaKey = new InviaKey(getKeyPort);
        inviaKey.start();
        // Cryptography: end

        offerte = new ArrayList< Offerta>();
        limite = deadline;
        this.port = port;
        accepter = new AstaAccepter(port);
        accepter.start();
    }

    /**
     * Thread per la gestione dell'invio della chiave pubblica
     *
     * @author Raffaele Giordanelli
     */
    private class InviaKey extends Thread {

        private int inviaKeyPort;
        private ServerSocket servInviaKey;

        InviaKey(int p) {
            try {
                // Creazione del ServerSocket sulla porta inviaKeyPort
                inviaKeyPort = p;
                servInviaKey = new ServerSocket(inviaKeyPort);

                // inizializza un generatore di coppie di chiavi usando RSA
                KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
                kpg.initialize(1024);
                // genera la coppia
                kp = kpg.generateKeyPair();

                // Inizializzo un cifrario che usa come algoritmo RSA, come
                // modalità ECB e come padding PKCS1
                decipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                // Lo inizializzo dicendo modalità di codifica e chiave privata
                // da usare
                decipher.init(Cipher.DECRYPT_MODE, kp.getPrivate());

                // Inizializzo un cifrario che usa come algoritmo RSA, come
                // modalità ECB e come padding PKCS1
                cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                // Lo inizializzo dicendo modalità di codifica e chiave privata
                // da usare
                cipher.init(Cipher.ENCRYPT_MODE, kp.getPrivate());

            } catch (Exception e) {
                System.err.println(e);
            }
        }

        @Override
        public void run() {
            try {
                while (true) {
                    Socket s = servInviaKey.accept();

                    InputStream in = s.getInputStream();
                    in.read();

                    OutputStream out = s.getOutputStream();
                    out.write(kp.getPublic().getEncoded());
                    out.close();
                }
            } catch (IOException ioe) {
                System.err.println(ioe);
            }
        }
    }

    /**
     * Thread per gestire le offerte ricevute in tempo utile
     *
     * @author Raffaele Giordanelli
     *
     */
    class AstaAccepter extends Thread {

        private int port;
        private ServerSocket serv;
        private boolean accept;
        
        AstaAccepter(int p) {
            try {
                port = p;
                serv = new ServerSocket(port);
                accept = true;
            } catch (IOException ioe) {
                System.err.println(ioe);
            }
        }

        
        
        
        
        @Override
        public void run() {
     
     
    
            
            while (accept) {
                try {
                    Calendar now = Calendar.getInstance();
                    serv.setSoTimeout((int) (limite.getTimeInMillis() - now.getTimeInMillis()));
                    Socket k = serv.accept();
                    InputStream in = k.getInputStream();
                    PrintWriter out = new PrintWriter(k.getOutputStream(), true);

                    // Cryptography: begin
                    // Salvo la scomemssa inviata al server
                    byte[] offertaBytes = new byte[1000];
                    int numByte = in.read(offertaBytes);
                    offertaBytes = Arrays.copyOf(offertaBytes, numByte);
                    byte[] offertaDecriptata = decipher.doFinal(offertaBytes);

                    // Cryptography: begin

                    String line = new String(offertaDecriptata);

                    System.out.println("offerta decifrata=" + line);

                    int pos = line.indexOf(" ");
                    
                    double importo = Double.parseDouble(line.substring(pos + 1));
                    InetAddress ip = k.getInetAddress();

                    Offerta s = new Offerta(importo, ip);
                   
                    offerte.add(s);

                    // manda ok
                    out.println("Offerta accettata.");
                    out.close();
                    k.close();
                    System.out.println("Ricevuta offerta " + ip + " " + " " + importo);

                } catch (SocketTimeoutException ste) {
                    accept = false;
                    System.out.println("Tempo a disposizione per le offerte terminato");
                }// catch
                catch (IOException ioe) {
                    System.err.println(ioe);
                } catch (Exception e) {
                    System.err.println(e);
                }
            }// while
            try {
                serv.close();
            } catch (IOException ioe) {
                System.out.println(ioe);
            }
        }// run
    }// AstaAccepter

    /**
     * Thread per gestire le offerte ricevute fuori tempo massimo
     *
     * @author Raffaele Giordanelli
     *
     */
   
    
    
    
    class AstaDenier extends Thread {

        private int port;
        private ServerSocket serv;
        private boolean closed;

        AstaDenier(int p) {
            try {
                port = p;
                serv = new ServerSocket(port);
                closed = true;
            } catch (IOException ioe) {
                System.err.println(ioe);
            }
        }

        public void reset() {
            closed = false;
        }

        public void run() {
            try {
                while (closed) {
                    //controllare chiusura inserzione 
                    Socket k = serv.accept();
                    PrintWriter out = new PrintWriter(k.getOutputStream(), true);
                    out.println("Offerte chiuse");
                    out.close();
                    k.close();
                    System.out.println("Rifiutata offerta");
                }// while
                serv.close();
            } catch (IOException ioe) {
                System.err.println(ioe);
            }
        }// run
    }// AstaDenier

    /**
     * Attende fino al termine del thread AstaAccepter. Quando il metodo
     * termina, le offerte sono automaticamente chiuse.
     */
    public void attendiChiusuraOfferte() {
        try {
            accepter.join();
        } catch (InterruptedException ie) {
            System.err.println(ie);
        }
    }

    /**
     * Avvia il thread AstaDenier che rifiuterà le offerte in arrivo.
     */
    public void chiusuraOfferte() {
        denier = new AstaDenier(port);
        denier.start();
    }

    /**
     * Fa terminare anche il thread AstaDenier.
     */
    public void resetServer() {
        denier.reset();
    }

    /**
     * @return la lista delle offerte vincenti, ovvero con importo sul cavallo
     * passato come parametro
     */
    public String controllaOfferte() {

        LinkedList<Offerta> elenco = new LinkedList<Offerta>();
        Iterator iteratore = offerte.listIterator();
        
        return new String("Ha vinto matteo!");
    }

    public void login(){}
    
    
    /**
     * Invia a tutti i client in multicast l'elenco dei vincitori
     */
    public void comunicaVincitori(String OffertaVincente, InetAddress ind, int port) {

       
        try {
            MulticastSocket socket = new MulticastSocket();
            byte[] buf = new byte[256];
            String m = OffertaVincente;
          
            // Cryptography: begin
            // cripta con la chive privata i dati per inviarli allo
            // scommettitore
            buf = cipher.doFinal(m.getBytes());
            // Cryptography: end

            DatagramPacket pk = new DatagramPacket(buf, buf.length, ind, port);
            socket.send(pk);
        } catch (IOException ioe) {
            System.err.println(ioe);
        } catch (Exception e) {
            System.err.println(e);
        }
    }
    public void comunicaPrezzoCorrente(Inserzione ins, InetAddress ind, int port) {

        Double pa = ins.getPrezzoAttuale();
        try {
            MulticastSocket socket1 = new MulticastSocket();
            byte[] buf = new byte[256];
            String m = "" + pa;
             // Cryptography: begin
            // cripta con la chive privata i dati per inviarli allo
            // scommettitore
            buf = cipher.doFinal(m.getBytes());
            // Cryptography: end

            DatagramPacket pk = new DatagramPacket(buf, buf.length, ind, port);
            socket1.send(pk);
        } catch (IOException ioe) {
            System.err.println(ioe);
        } catch (Exception e) {
            System.err.println(e);
        }
        
}
    
    
    public static void main(String[] args) {

        int serverPort = 8001;
        int clientPort = 8002;

        // Cryptography: begin
        int getKeyServerPort = 8443;
        // Cryptography: end

        try {
            InetAddress multiAddress = InetAddress.getByName("230.0.0.1");

            Calendar deadline = Calendar.getInstance();
            deadline.add(Calendar.SECOND, 10);

            AstaServer server = new AstaServer(serverPort, getKeyServerPort, deadline);
            server.attendiChiusuraOfferte();
            server.chiusuraOfferte();
            String OffertaVincente=server.controllaOfferte();
            //metodo che calcola l'offerta maggiore.
            System.out.println("E' risultato vincitore l'offerente: " + OffertaVincente);
             server.comunicaVincitori(OffertaVincente, multiAddress, clientPort);
            System.out.println("Vincitore:");
            System.out.println(OffertaVincente);

            Thread.sleep(150000);
            server.resetServer();
        } catch (InterruptedException ie) {
            System.err.println(ie);
        } catch (UnknownHostException uhe) {
            System.err.println(uhe);
        }

    }// main
}// AstaServer